Age | Commit message (Collapse) | Author | Files | Lines |
|
Methods are resolved as part of type resolution so scanning ribs early
on will results in false warnings about unused methods.
|
|
We keep temporary's for each block in order for the result to be
referenced. For example:
let x = { test() + 1 };
This can be resolved into:
{
let x:i32;
_tmp1:i32;
{
_tmp2:i32 = test();
_tmp1 = _tmp2 + 1;
}
x = _tmp1;
}
Fixes #189
|
|
Rust does not allow functions/methods/constants/static definitions to
shadow otherwise you end up with unuseable items.
|
|
This also enhance ArithmeticOrLogicalExpr rules and associated error
handling to propagate up the stack.
|
|
This is the building block in adding support for methods and the self
keyword.
Fixes: #111
|
|
Seperated test cases and one to combine them to help navigate any
potential failures later on.
|
|
This greatest common divisor function demonstrates that recursion is
working.
|
|
This supports basic function pointers in rust most of the code was already
there to infer this but this has now helped tidy it up and make it work.
Fixes #184
|
|
In order to assign to a name we must ensure the LHS is a valid expression
to assign to. This leads onto actually checking if this is a mutable
declaration or not.
Once these checks pass the name resolver we can in GIMPLE create immutable
types for these declarations to help with optimization.
Fixes #77
|
|
Arrays can only be indexed by usize and this enforces that rule. These
types are sized based on the pointer size of the host arch.
Fixes #87
|
|
In order to properly handle all integer types and infer we must follow HM
algorithm. This means when we unify every type in the resolver this should
keep a chain of HirId of references such that when/if the type is resolved
it lookup tables can be updated for the Backend to compile to Gimple.
Consider the case:
fn test(x:u32) -> u32 {...}
let a = test(1);
The VarDecl here will have the type let a:<I?> = test<u32>(1<I?>).
Since this integer combines with the parameter x:u32 the type resolver
knows at this point these must be a u32.
let a;
a = 1;
let b:u32 = a;
This is more subtle
let a:<?>
a:<?> = 1<I?>
let b:u32 = a<I?>;
Since the integer inference variable combines with u32 all previous
references can be updated to u32 at this point.
In the basic case of:
let a;
a = 1;
This resolves down to:
let a:<I?>;
a<I?> = 1<I?>
It is not until we complete type-inference we can iterate all the
resolved types and HirIds and default any <I?> to i32 and any <F?> to f32.
Any remaining general inference variable are errors.
|
|
TyTy::ParamType is meant to be used to represent Generic Types which is
not handled yet as part of this current milestone.
|
|
GCC uses qualified types to create const immutability.
|
|
Parameter types can be resolved to their base type in combination rules.
|
|
This expands the AST::CompoundAssignmentExpr into and HIR::AssignmentExpr
with the asignee being referenced for lhs and a new artificial
HIR::ArithmeticOrLogicalExpression with lhs asignee and rhs the rhs
of the original CompoundAssignment expr.
|
|
This is an example of a unary expression in gimple. The rules for enforcing
the types are observed in the type resolver here too.
Unary negate cannot be applied to bools but only integers and floats.
Unary not cannot be applied to floating points but can be applied to
integers and bools.
|
|
This adds test cases and enforces the type rules for ArithmeticOrLogical
Operators.
|
|
This fixes the expression type resolution to coerce these into bools. For
LazyBoolExprs && and || the lhs and rhs are bools.
|
|
The input needed to be skipped once the operator was parsed to ensure
the lexer did not duplicate the operator. |= still fails but this looks
to be a parser problem.
|
|
When we use anything other than builtin types for returns or parameters
the type resolver was missing the NodeId mappings meaning it would
alawys fail to resolve them.
Then in gimple conversion we need to be able to reference the already
created RECORD types instead of always creating new instances.
|
|
The gimple interface requires us to have the fields in order as to the
Algebraic Data Type which it references.
|
|
This creates implicit FieldAccessExpr or TupleIndexExprs for the missing
fields in the constructor using the base struct as the receiver.
|
|
This resolves each identifier for its respective field. It includes fixes
for the TypeResolver to print errors instead of asserts where we loose
decent debug info.
|
|
For TupleStructs the constructor can take field indexes to support
change or ordering of the fields.
|
|
Now we can type resolve and reference the results from TupleIndexExpr's.
|
|
This adds in tuple struct support with name and type resolution. The
arguments and number of arguments are validated against. Test cases
added for those errors too.
|
|
The type resolver must ensure LHS for assignments where the LHS was
infered to be ? and the node mappings have a definition ID we know
the declaration id and can reassign the TyTy so further references know
its type.
|
|
... as used otherwise, in this file. And, this avoids:
[...]/source-gcc/gcc/rust/parse/rust-parse-impl.h:12243:72: error: could not convert '{false, true}' from '<brace-enclosed initializer list>' to 'Rust::ParseRestrictions'
= {/* can_be_struct_expr = */ false, /* entered_from_unary = */ true};
^
|
|
GCC doesn't like that:
In file included from [...]
./mm_malloc.h:42:12: error: attempt to use poisoned "malloc"
return malloc (__size);
^
See commit e7b3f654f2ab0400c95c0517387a9ad645a5c4cd, for example.
|
|
This adds in struct field expressions and should be generic enough for
tuples later on.
|
|
This was using LetStmt->Pattern.as_string which included mut in the string
dump. This makes the gimple nodes harder to debug as the name is (mut a)
insteaad of a for example.
|
|
We must ensure the backend can support compilation of things declared
lexically after they are referenced. This scans the toplevel except
functions which are handled as we reference them. To make that generic
enough for all toplevel items will be a move to query based compilation
which still needs planning.
|
|
This makes the expression handling support exprs within parens. Such as:
x = (2*a) + 3;
|
|
|
|
More testing is required but this adds tuples apart from TupleStructs
which are parsed as CallExpr. This will be the primitives required to
finish that work.
|
|
This change enforces strict type checkon on all ExprWithBlock. This
includes unreachable tail expressions. Specific test cases have been added
for context to ensure the failure cases are hit accordingly.
This change also improves the diagnostic errors for mismatched types
where the reference HirId was lost leading to default locations.
|
|
It is possible to assign and declare variables of unit-type which
translate down to zero sized void_type_node.
More work is needed to handle array and ADT types using unit-type
when emiting gimple. The name+type resolution should be generic enough.
|
|
This change will need more thought later when it comes to traits and
generics etc.
Fixes #136
|
|
This lead to cleanup of the name resolver as the usage of mappings means
that in a given rib if there are no references to a decl NodeId that
means it was not used.
To get on par with the offical rust compiler it should be allowed to have
a reference where the name was assigned but not used but this might be a seperate pass.
|
|
This means that paramters are scoped and shadowed correctly. Currently
the resolver is treating all paramters are shadowing each other if they
have the same name which is incorrect.
|
|
This ensures the compiler respects scoping and shadowing rules of
blocks added within an enclosing scope.
|
|
pattern first before the init expression. This lead to a situation
where shadowing rules were broken.
Example:
let x = 1;
let x = x + 1;
In this example the code was referencing the 2nd LetStmt as the resolved
name for the Identifier reference.
|
|
This will help enforce consistency of visitors to fix issues with
TyTy unification rules.
|
|
Rust is permissive for integers being marked as floats so the check in the
lexer can be removed here.
|
|
For implict returns we must consider cases with a block having multiple
returns:
HIR::BlockExpr Stmts {
...
return x
}
HIR::BlockExpr final_expression {
x + 1
}
Although the code above is bad this is valid rust code and the rust
compiler correctly identifies the final_expression as unreachable.
This dead code eliminiation is done as part of AST to HIR lowering.
Type resolution examines all blocks to identifiy if they terminate
a function with a return/final expression it must correspond accordngly.
If the block is the final block the resulting termination of the block
must match the return type of the function, else the block must conform
to unit type.
|
|
This also ensure the type suffix is respected against the number.
|
|
for the ASM name similar to functions.
|
|
|
|
We need to ensure all suffix of literals are handled in a subsequent PR.
|
|
This change propagates the PrimitiveCoreType to AST and HIR so
the suffix can be examined.
|