| Age | Commit message (Collapse) | Author | Files | Lines |
|
|
|
837: HIR::IdentifierPattern had all fields public r=philberty a=philberty
This makes the fields private again and adds the missing getter for the
identifier.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
This makes the fields private again and adds the missing getter for the
identifier.
|
|
The AST constructors implicitly generate new NodeId's, their associated
copy/move constructors ensure that they preserve the NodeId correctly.
The AST::Pattern's here incorrectly had a constructor in the abstract
base class which was generating the NodeId's but when this is used
within AST::MatchArms the fields contain these patterns which can get
copied/moved causing new NodeId's to be generated which then throws off
typechecking as the NodeId changes during HIR lowering and thus each of the
ID's are all of by one during typechecking.
|
|
835: Add name-resolution and HIR lowering pass for MatchExpr r=philberty a=philberty
This adds the name-resolution and HIR lowering pass for the match-expr
the type checking pass patch needs some work to be split up but these are
two nice isolated commits which are easier to read.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
|
|
|
|
This adds a naieve first pass approach to enum type code generation. The
original idea was to use GCC's QUAL_UNION_TYPE but I have ran into issues
with the DECL_QUALIFIER as my understanding of how this works is incorrect.
This takes an enum such as:
```rust
enum AnEnum {
A,
B,
C (char),
D (x: i64, y: i64),
}
```
And turns this into one big union consisting of all fields as RECORD_TYPES.
```c
union AnEnum {
record A { RUST$ENUM$DISR };
record B { RUST$ENUM$DISR };
record C { RUST$ENUM$DISR, char };
record D { RUST$ENUM$DISR, i64, i64};
}
```
see: https://github.com/bminor/binutils-gdb/blob/527b8861cd472385fa9160a91dd6d65a25c41987/gdb/dwarf2/read.c#L9010-L9241
With the RUST$ENUM$DISR being the first field in all of the records this
means the alignment allows for indirect memory access of the struct to
use it as a qualifier field to figure out which variant is currently in
use. The data-less varients use their generated discriminat value during
type-checking the data variants use their HIR ID for their discriminant.
This will likely get redone to get improved GDB integration/updated to use
the QUAL_UNION_TYPE when we learn how to do this properly.
Fixes #79
|
|
832: Refactor TyTy::ResolveCompile pass to be in its own file r=philberty a=philberty
This name likely needs to be refactored, this class is used to take TyTy types
and compile them down to GCC tree's but take into account that we may have
already compiled this type before so to preserve the canonical types we
"resolve" the type if possible and then compile.
833: Refactor CallExpr and MethodCallExpr into rust-compile-expr.cc r=philberty a=philberty
Our compile times are very bad for the front-end code and this is part
of the drive to pull more implementation code out of headers and into
code files such that we can have smaller headers and many code files
to reduce recompilation of the same code.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
|
|
This name likely needs refactored, this class is used to take TyTy types
and compile them down to GCC tree's but take into account that we may have
already compiled this type before so to preserve the canonical types we
"resolve" the type if possible and then compile.
|
|
The type checking over the fields of each variant was using the wrong
iterator causing the type checker to go out of bound in the case where
there were more variants than fields within the variant.
```
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 2) >= this->size() (which is 1)
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
...
-7 0x000000000119dcfc in std::vector<Rust::TyTy::StructFieldType*, std::allocator<Rust::TyTy::StructFieldType*> >::_M_range_check (this=0x426fb90, __n=2) at /usr/include/c++/9/bits/stl_vector.h:1070
-8 0x000000000119a2e5 in std::vector<Rust::TyTy::StructFieldType*, std::allocator<Rust::TyTy::StructFieldType*> >::at (this=0x426fb90, __n=2) at /usr/include/c++/9/bits/stl_vector.h:1091
-9 0x000000000117ead7 in Rust::TyTy::VariantDef::get_field_at_index (this=0x426fb60, index=2) at ../../gccrs/gcc/rust/typecheck/rust-tyty.h:1080
-10 0x00000000011c7523 in Rust::TyTy::ADTRules::visit (this=0x7fffffffce90, type=...) at ../../gccrs/gcc/rust/typecheck/rust-tyty-rules.h:1050
-11 0x00000000011b52a4 in Rust::TyTy::ADTType::accept_vis (this=0x4271120, vis=...) at ../../gccrs/gcc/rust/typecheck/rust-tyty.cc:642
-12 0x00000000011c2d80 in Rust::TyTy::BaseRules::unify (this=0x7fffffffce90, other=0x4271120) at ../../gccrs/gcc/rust/typecheck/rust-tyty-rules.h:85
-13 0x00000000011b552e in Rust::TyTy::ADTType::unify (this=0x426fe30, other=0x4271120) at ../../gccrs/gcc/rust/typecheck/rust-tyty.cc:670
-14 0x000000000118e49f in Rust::Resolver::TypeCheckExpr::visit (this=0x7fffffffd070, expr=...) at ../../gccrs/gcc/rust/typecheck/rust-hir-type-check-expr.h:1302
```
|
|
829: Constant folder now returns error_mark_node instead of nullptr r=philberty a=npate012
Removed nullptr checking on results from constant folder because when the
result is already error_mark_node, we no longer need to check if the result
is nullptr.
Fixes #692
Signed-off-by: Nirmal Patel <npate012@gmail.com>
830: Cleanup lambdas within some AST types r=philberty a=dafaust
Cleanup constructs like:
```C
struct_decl.iterate ([&] (AST::TupleField &field) mutable -> bool {
... /* do stuff with field */
});
```
For the following AST classes:
- AST::StructStruct
- AST::TupleStruct
- AST::Union
- AST::ArrayElemsValues
Fixes: #714
Fixes: #715
Fixes: #716
Fixes: #720
Co-authored-by: Nirmal Patel <npate012@gmail.com>
Co-authored-by: David Faust <david.faust@oracle.com>
|
|
These constructs make working with the IR needlessly complicated for
static analysis. Replace with simple for loops, and delete the old
Union::iterate () method.
Fixes: #716
|
|
These constructs make working with the IR needlessly complicated for
static analysis. Replace with simple for loops, and delete the old
StructStruct::iterate () method.
Fixes: #714
|
|
These constructs make working with the IR needlessly complicated for
static analysis. Replace with simple for loops, and delete the old
TupleStruct::iterate () method.
Fixes: #715
|
|
These constructs make working with the IR needlessly complicated for
static analysis. Replace with simple for loops, and delete the old
ArrayElemsValues::iterate () method.
Fixes: #720
|
|
Removed nullptr checking on results from constant folder because when the
result is already error_mark_node, we no longer need to check if the result
is nullptr.
Fixes #692
Signed-off-by: Nirmal Patel <npate012@gmail.com>
|
|
This script tries to isolate our changes to GCC minus the changes to
gcc/config so that we can visualize our development history.
|
|
This adds in support for deref lang-item operator overloads. Deref operator
overloading is an interesting case of the libcore interaction with the
compiler. The deref operator lang item is:
```rust
pub trait Deref {
type Target;
fn deref(&self) -> &Self::Target;
}
```
It has two default impl's one for '&T' and '&mut T' to apply genericly.
The reason it is interesting is from the prototype the deref lang item
always returns &Self::Target in all cases regardless of mutability, the
lang item here is designed to wrap up any dereference such that when
applied it guarentees the type system you will get back an immutable
reference to something. The reason for doing this is more clear when
thinking about autoderef and method-resolution and how you apply
dereference operations to custom types and a test case is included for
that.
The autoderef mechanism will now need to be updated to support drefs fully.
Fixes #809
|
|
823: Support generics on operator overlads. r=philberty a=philberty
This ports over some code from the method-call expr to try and infer the
arguments in the function definition when required.
Addresses #809
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
821: Always update the type context for monoprhized items except type params r=philberty a=philberty
We need to update the type context type with the newly monomorphized types
we guarded against ADT's and functions because they were never added before
though this does not work for generic reference's to ADT's this updates
the check accordingly.
822: Make TyTy::BaseType::contains_type_parameters non-virtual r=philberty a=philberty
This is a second cleanup to the generic interfaces in the type system. The
helper for contains type parameters is akin to asking if a type is concrete
or not. If a type is not concrete ie: contains type parameters then this
can be leveraged instead of adding more complexity.
The TyTy::BaseType::is_concrete is already an abstract method forcing
all types to implement it, this makes it much safer and fixes some bad
infinite recursion bugs if we asked if a type contained type-parameters
which in turn somtimes aksed if it was concrete or not which in turn
again called contains_type_parameters. This cleans it all up. More
cleanup to these interfaces can be done over time.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
820: Bug fix mutability checks in can_eq for autoderef r=philberty a=philberty
Rust is permissive about mutablity in type checking for example, if we have
a function:
fn foo(a:&bar) { ... }
fn caller() {
let a:&mut bar = ...;
foo(a);
}
This is valid since the mutable reference to bar is valid to be turned into
an immutable reference without any conversion. Like in C a non-const
pointer is valid to be passed to a const pointer inferface.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
817: Remove bad mutability check pass r=philberty a=philberty
This was an initial pass to try and ensure all assignments were valid
with respect to the binding mutability. This pass cannot be done at the
name resolution level and in rustc is achieved on mir as part of the borrow
checker. This patch removes this pass and associated test cases.
This set of patches also adds support for indirection around array index
expressions.
Fixes #815
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
This ports over some code from the method-call expr to try and infer the
arguments in the function definition when required.
Addresses #809
|
|
This operator overloading function was extracted from the callers within
compound assignment etc, where we needed to be able to fall back to code
within the same function. This improves the error handling to return early
when there are no such lang-items or no available method instead of trying
to continue. It flattens the conditional's previously required in the code
path.
|
|
This is a second cleanup to the generic interfaces in the type system. The
helper for contains type parameters is akin to asking if a type is concrete
or not. If a type is not concrete ie: contains type parameters then this
can be leveraged instead of adding more complexity.
The TyTy::BaseType::is_concrete is already an abstract method forcing
all types to implement it, this makes it much safer and fixes some bad
infinite recursion bugs if we asked if a type contained type-parameters
which in turn somtimes aksed if it was concrete or not which in turn
again called contains_type_parameters. This cleans it all up. More
cleanup to these interfaces can be done over time.
|
|
We need to update the type context type with the newly monomorphized types
we guarded against ADT's and functions because they were never added before
though this does not work for generic reference's to ADT's this updates
the check accordingly.
|
|
Rust is permissive about mutablity in type checking for example, if we have
a function:
fn foo(a:&bar) { ... }
fn caller() {
let a:&mut bar = ...;
foo(a);
}
This is valid since the mutable reference to bar is valid to be turned into
an immutable reference without any conversion. Like in C a non-const
pointer is valid to be passed to a const pointer inferface.
|
|
In rust the mangling of names needs to handle cases such as qualified paths
<&mut T as Deref>::deref. Assemblers cannot handle '&' and whitespace
otherwise we will fail to assemble the functions, the legacy mangling
scheme turns all reference's '&' into 'RF' and all whitespace into '$'
this means we can mangle more complex canonical paths. Which are needed
in order to support the deref operator overloading.
|
|
When we have an array-index expr rust allows the array reference to be a
reference and the compiler is meant to add in the required implicit
indirection. This checks for this senario and injects the indirection
during code-generation.
Fixes #815
|
|
This was an initial pass to try and ensure all assignments were valid
with respect to the binding mutability. This pass cannot be done at the
name resolution level and in rustc is achieved on mir as part of the borrow
checker. This patch removes this pass and associated test cases.
We will be able to do this type of validation on the GCC tree's such as
the C/C++ family const checks we may be able to reuse.
Fixes #815
|
|
Some HIR::TypeNoBounds have a gcc_unreachable() unpon usage of their
respective copy constructors this change moves the instances of
FunctionParams to avoid the copy.
|
|
GCC requires VAR_DECL's and PARAM_DECL's to be marked with TREE_ADDRESSABLE
when the declaration will be used in borrow's ('&' getting the address).
This takes into account the implicit addresses when we do autoderef in
method resolution/operator-overloading.
This patch keeps a seperate side table for the VAR_DECL/PARAM_DECL hir-id's
for lookup. The typechecker marks these id's using
AddressTakenResolver::SetAddressTaken (HIR::Expr&);
Its quite simple as it only cares about paths such as:
- PathInExpression
- QualifiedPathInExpression
- IdentifierExpression
The rest of the expression types will be folded into temporary values
anyway so they don't need to be marked as needs_address.
Fixes #804
|
|
813: Support QualifiedPathInType's within the same Trait r=philberty a=philberty
The first implementation of qualified paths assumed that they only exist
within trait-impl blocks. Trait impl blocks have the same canonical paths
of <type as trait_path>::segment form but this type of path is more generic
than this.
see the commit for more details on the implementation.
Fixes #739
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
The first implementation of qualified paths assumed that they only exist
within trait-impl blocks. Trait impl blocks have the same canonical paths
of <type as trait_path>::segment form but this type of path is more generic
than this.
This patch changes the name resolver to allow for failures in looking up
the qualified path within the type namespace since it will not exist in
this case and updates the type checking code to be more permissive when
used outside of trait impl blocks to simply allow us to resolve this type
to the associated trait item as we expect. Usually the code here tries
to setup any associated types based on the associated impl block but this
is a difference case.
Fixes #739
|
|
This removes the implicit Self::associate_type paths from the name resolver
these are unnessecary with the updates in the type system to resolve these.
|
|
|
|
This set to a pair is simply a map and the added complexity here is
unnecessary.
|
|
These names are poor and are easily conflated with the singleton mappings
which contain all mappings known in this compilation unit.
|
|
Toplevel ribs should be the same id of the Crate this allows is to scan
all toplevel ribs simply by knowing the crate number.
|
|
Before the TypePath resolution was updated to support associated type paths
and projections, we used an implict name hack of Self::<associated-type> as
well as the usual TraitName::<associates-type> this was a hack in the short
term to get things working which can now be removed.
Addresses: #739
|
|
810: Fix MethodCalls for covariant impl blocks r=philberty a=philberty
I think we need to research more into how we probe for potential candidates
for method calls. This fixes a few bugs going on in #808 one where the
canonical path was empty and one where we fail to probe directly on the
receiver of reference types to impl blocks but we must be able to also support
that autoderef means that a receiver's root type might actually be the type we
care about for example a reference to a generic type-parameter and we probe
its bounds for candidates for example. Lets consult the rustc code and references on this.
Fixes #808
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
Impl blocks Self type is a TypeNoBouns which means it can be for types
such as: impl<T> &T {}.
I think we might need to change the probe algorithm for method calls to be
fully based on the autoderef rather than trying to filter based on the Self
type. More investigation is needed for the probe phase here.
Fixes #808
|
|
|
|
When we must infer the substitutions on method calls we must make sure to
unify the self arguments from the receiver, taking into account the
autoderef mechanism. This enforces the type checks and fixes up any
inference variables along the way.
Addresses #808
|
|
|
|
This fixes the ice for TypeNoBounds canonical paths for reference types
which was not implemented resulting in empty paths for the canonical
path of impl_blocks for example.
A Fixme has been added to point out that we should update this interface
to only take AST::TypeNoBounds.
Fixes #808
|
|
|
|
|