Age | Commit message (Collapse) | Author | Files | Lines |
|
666: Super Traits Support r=philberty a=philberty
This adds initial super traits support. Super traits are implemented by
explicitly adding the super trait bound to the implicit Self type parameter
on traits. This will improve as we enhance the type system to handle bounds
and where constraints in general as they reuse all that same code path.
Fixes #565
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
661: Add support for choosing other builtin GCC calling conventions r=philberty a=philberty
Add support for some other ABI options.
I was able to test this with linking against some C code but
these options like stdcall seem to be limited to 32 bit mode
```rust
extern "stdcall" {
pub fn test(a: i32) -> i32;
}
extern "C" {
fn printf(s: *const i8, ...);
}
fn main() -> i32 {
unsafe {
let a = 3;
let res = test(a);
let a = "%i\n\0";
let b = a as *const str;
let c = b as *const i8;
printf(c, res);
}
0
}
```
```c
__attribute__ ((stdcall)) int test(int x) {
return x + 3;
}
```
Compiling like this:
```
$ gccrs -g -O0 -m32 -c test.rs -o test.o
$ gcc -g -O0 -m32 -c lib.c -o lib.o
$ gcc -m32 -o test test.o lib.o
```
More testing will be required over time here but this was
kind of fun to see that it worked.
663: Move module output test case from compile/ to execute/ r=philberty a=CohenArthur
Fixes [this issue](https://github.com/Rust-GCC/gccrs/pull/639#discussion_r705922519) by `@tschwinge`
I think this shows that we need to figure out a better way to keep test files and their modules, as pointed out by `@dkm` [here](https://github.com/Rust-GCC/gccrs/pull/639#issuecomment-905457557). Here, the modules/ directory is a straight up duplicate of the other one in compile/ which I'm not a fan of.
I have no experience with having a separate .exp in the subdir but I can try and I think that it would be better. Maybe it can also be simpler if the regex to match *.rs files only looks inside one level of subdirectories? But I can think of a few places where this might be an issue
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Co-authored-by: CohenArthur <arthur.cohen@epita.fr>
|
|
Super Traits are simply TraitBounds upon the implict Self TypeParameter,
such that a trait with a super trait bound almost ends up looking like this
trait A : B { } -> trait A where Self: B { }
|
|
When we have generic code that calls other generic code the type system
will have already setup the side tables for substituions and at this point
the referenced generic code does not need to be substituted again.
|
|
|
|
|
|
path attributes were used wrongly in two ways:
1/ The attribute's value would still contain extra data such as an equal
sign and whitespaces, which need to be discarded in order to fetch the
proper file path.
2/ #[path]s are relative to the directory where the current source file
is located. So we actually need to compute them later on down the line,
once the including directory has been figured out.
Another issue was that in the case that no candidates were found, or too
many were founds, the function `process_file_path` would still return
"successfully" despite erroring out. This causes the function to return
early and thus not assign any string to the `module_file` member.
We also have the ability to emit an error for the module's location,
which looks better for the user, instead of using a new `Location()`
like the session manager does (because it can't do otherwise)
|
|
Co-authored-by: Thomas Schwinge <thomas@schwinge.name>
|
|
Super trait bounds need to be lowered to HIR.
|
|
Trait bounds signify super-traits this adds name resolution for them.
|
|
|
|
GCC adds these as options to the function type as far as I can see, I was
able to test this with linking against some C code. More testing is
required here.
|
|
659: Initial intrinsics builtin block r=philberty a=philberty
This is the initial piece to get the simple intrinsic's mapped over to GCC ones. The
GCC wrapper contains a mapping system of rust names over to the builtin gcc names
as far as I can tell gcc will allow for fallback onto linking against -lm.
I think this will be a nice piece of work for new contributors, given the number of intrinsics
Addresses #658
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Co-authored-by: Thomas Schwinge <thomas@codesourcery.com>
|
|
639: External module expansion r=philberty a=CohenArthur
Needs #638
This PR parses the file associated with an external module and allows their compilation. The two test cases are not currently passing, and the locations will be inexact (the filename for the parsed module will just show as random characters), so the PR is still a draft.
Co-authored-by: CohenArthur <arthur.cohen@epita.fr>
|
|
|
|
into 'rust/compile/torture/intrinsics-1.rs'
Avoid proliferation of such execution tests: such builtins typically are mapped
to regular function calls (which we already do have confidence that they work
correctly), so it ought to suffice to just scan '-fdump-tree-original'.
|
|
|
|
|
|
|
|
We need a way to be able to turn intrinsic function prototypes and
associated function calls into the GCC builtin. The GCC wrapper was
reused from GO and the math builtin's don't seem to be correct, here
I changed __builtin_sin to __builtin_sinf to get the float version.
See builtins.def for the other builtins.
|
|
We need to know the specified ABI in order to determine the linkage, it
might be a plain old rust function, an extern C function or a compiler
intrinsic and each of these needed to be handled differently.
|
|
656: Add mangling switch r=philberty a=CohenArthur
Add option to choose mangling scheme.
Closes #429
This PR splits the `Mangler` class in its own set of header and source and adds the base for v0 name mangling.
You are now able to specify the mangling scheme to use using `-frust-mangling=<value>`.
When inputting an invalid value, the compiler errors out using `unrecognized command-line option `-frust-mangling=<not_valid>`. Is there a better way to do this? Is there also a way to test this behaviour using dejagnu?
Co-authored-by: CohenArthur <arthur.cohen@epita.fr>
|
|
|
|
|
|
|
|
Co-authored-by: Marc Poulhies <dkm@kataplop.net>
|
|
Make HIT EnumItem class an Item, not VisItem like in the AST. At the
HIR level EnumItems shouldn't have visibility anymore.
Move struct_field_name_exists to rust-ast-lower.cc with the
declaration in rust-ast-lower.h to make it reusable in the different
visitors.
Add a new ASTLoweringEnumItem that can be used from ASTLoweringItem
and ASTLoweringStmt. It checks the EnumItems don't have visibility and
that EnumItemStruct fields are not duplicated.
Add a new testcase 'bad_pub_enumitems.rs' to check the no-visibility and
no-duplicates properties hold.
|
|
Generate paths for Enum and EnumItem AST NodeIds and resolve the types
of tuple and struct enum items.
EnumItems always have the Enum as prefix. To make this work for
ResolveStms (declaration statements are not given a canonical path) we
add an enum_prefix to be used when resolving EnumItems.
For ResolveType the tuple and struct fields get resolved using the
Enum type scope.
Add tests for toplevel or stmt enums with duplicate variant names. And
adjust the tuple_enum_variants.rs testcase to expect unused name
warnings.
|
|
Syntactically enum items can have a visibility. The visibility has to
be removed (through a cfg attribute or macro) before they get lowered.
The semantic checking will be done when we implement lowering enum items.
Make the AST EnumItem class a VisItem. This simplifies things a little
for cloning items, handling outer attributes and will help when adding
EnumItem (sub)classes to AST visitors (so they can be handled as
Items). Also add a get_identifier method to Enum and EnumItem.
|
|
|
|
|
|
655: Generic Qualified Paths r=philberty a=philberty
This fixes how we handle associated types in relation to generic
traits. Generic traits are interesting because, a TypePath usually
resolves to a normal TyTy type which can be substituted using the
mapper classes, but a trait is a definition of behaviour which
is made up of types, constants or functions. In order to handle
generic traits we must add substitution support to the associated types
which are represented by projections see this commit for detail on the changes
0798add3d3c1bf4b20ecc1b4fa1047ba4ba19759
Also see https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/sty/struct.ProjectionTy.html
Fixes #434
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
This extends the ProjectionType which represents an implemented associated
type with its own substitution mappings. The problem is a TypePath to a
trait does not represent a single TyTy primitive type, the type system
handles generics in an interesting way. Take for instance the case of a
generic impl block:
impl<T> Foo<T> {
fn Bar<Y>(self, a:T, b:Y) {}
}
The compiler treats an impl block as the parent so that all items inherit
from this, which is why rustc calls these inherent-impl-blocks. So
in order to handle generic arguments we need to "bind" them, and in rust
only some types actually support generic argument binding, at the moment
for gccrs it is, ADTTypes, FnTypes and Projections. Going back to the
example the TyTy for this function turns into:
fn Bar<T,Y>(Foo<T>, T, Y)
So when it comes to the generic traits its a similar process but the
difference is that traits contain associated types, these must be able
to bind the generic arguments such that we can substitute any covariant
types fully. But there is a layer of complexity and indirection here
consider the following example:
trait Foo<T> {
type A;
fn test(a: T, b: Self::A) -> (T, Self::A) {
(a, b)
}
}
struct Bar<T>(T);
impl<T> Foo<T> for Bar<T> {
type A = T;
}
When we deal with a trait with an optional trait function that uses the
associated types what actually happens here is that the type A in this
trait context is considered just a simple PlaceHolder which gets
setup within relation to its relevant impl block, so when we setup the
associated types it turns into:
Placeholder(A) ->
Projection<T>(Bar<T> as Foo<T>) ->
T
So it forms an recursive chain that must be substituted in relation to
what the paticular query is.
|
|
The canonical path for a traits does not include the generic arguments
but they must be resolved. This ensures we can actually resolve a generic
trait reference to the correct trait.
|
|
When we resolve a TypePath we expect this to resolve to a TyTy and to
substitute arguments accordingly. Qualified paths contain a trait reference
which can contain generic arguments, the problem here is that traits are
not a TyTy type since traits define behaviour not types. In order to
actually apply the substitutions in a future commit we must be able
to access these arguments in a sensible way first.
|
|
Traits implement self by creating an implicit Self TypeParam but when
we need to support generic arguments we must ensure Self is substituted
first so that the reset of the arguments are handled as we expect.
|
|
An Enumeration Expression is just like a Struct Expression. Old
versions of the Rust Reference described them separately. But since
they are syntactically exactly like a Struct Expression they are never
actually parsed. A Struct Expression can also be used to initialize
enums (and unions).
Remove the AST and HIR classes EnumExprField, EnumExprFieldIdentifier,
EnumExprFieldWithVal, EnumExprFieldIdentifierValue,
EnumExprFieldIndexValue, EnumExprStruct, EnumExprTuple,
EnumExprFieldless and EnumVariantExpr.
|
|
A StructExprUnit is parsed as an IdentifierExpr. An IdentifierExpr,
which is what we call a single segment PathInExpression.
After type checking, when generating gcc generic trees, if the
IdentifierExpr is a type reference (which must be a unit struct), then
a unit expression is generated.
Remove the AST and HIR StructExprUnit classes which are never used.
|
|
A StructExprTuple is parsed as a CallExpr. Both (can) start with a
PathInExpression followed by zero or more Expressions between
brackets.
Only, after type checking, when actually generating gcc generic trees
is a distinction made between a function call or tuple constructor.
Remove the AST and HIR StructExprTuple classes which are never used.
|
|
Qualified type paths are similar to qualified path expressions, in that
they must resolve the projection of the trait onto a type to receive the
correct associated type information.
|
|
Placeholder types are containers for associated types, the code-generation
pass has a check for is_unit on return types for functions so we can inject
void_type_node. This was a false positive for placeholders, placeholders
must resolve to check what their concrete implementation type actually is
for this type of query.
|
|
|
|
Qualified path types allow for TypePaths qualified with a paticular
associated impl and type;
|
|
|
|
651: Qualified paths have a mandatory initial segment r=philberty a=philberty
see https://doc.rust-lang.org/reference/paths.html#qualified-paths
The initial segment is mandatory this changes the AST to reflect this
it simplifies error handling down the line.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
|
|
Simply use get_locus () on the ImplItem.
Both the generics7.rs and generics8.rs testcase still pass.
|
|
HIRItem::get_impl_locus wasn't used and all subclasses already
implement get_locus.
|
|
|
|
Qualified path in type's initial segment is mandatory (+) any other
segments are optional after the fact. see
https://doc.rust-lang.org/reference/paths.html#qualified-paths
This change makes the AST have a mandatory field for the initial segment
the segment list now only contains the optional remaining segments.
|
|
Name shadowing in C++ is annoying, it can cause subtle errors like here,
the mappings which are substitition mappings, for example from an impl
block, impl<X,Y> Foo(X), the type resolver here looks for any unconstrained
type parameters by passing the relative mappings which can be null. Since
the util mappings class shadowed this we never actually got this hidden
nullptr segv. For QualifiedTypes we need to resolve the path similar to
path expressions and we will need to be able to access the shadowed util
hir mappings class.
|