Commit Graph

192831 Commits

Author SHA1 Message Date
Philip Herron 7609dfc63e Add missing unify rules for inference variables
Inference variables can unify with anything so this includes these
covariant types like references/slices etc. This patch is needed for more
complex type-checking in libcore and generics.
2022-04-12 13:49:30 +01:00
Arthur Cohen 23fc3ff7fe privacy: ctx: Add proper implementations for insert_reachability() and
lookup_reachability()

Inserting reach levels in the reachability_map should only be done if
the existing reach level is lower than the provided one. If the node is
not yet present in the reachability map, insert it no matter what
2022-04-12 14:26:23 +02:00
Arthur Cohen dfb5f548ce hir: Visibility: Add is_public() method 2022-04-12 14:26:23 +02:00
Arthur Cohen e01a814061 privacy: reach: Rename ReachLevel enum 2022-04-12 14:20:28 +02:00
Arthur Cohen 8bf037fede privacy: Add base for privacy-related visitors 2022-04-12 14:20:21 +02:00
Arthur Cohen 5449587438 hir: Add `Kind` enum to downcast safely 2022-04-12 14:20:18 +02:00
bors[bot] a5b38698aa
Merge #1103
1103: Lower AST::Visibility to HIR::Visibility properly r=CohenArthur a=CohenArthur

Fixes #1093

This should cover every case since the previous code simply created public HIR visibilities.

The PR refactors the HIR::Visibility struct to be tinier and a desugared version of the AST one.

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-04-12 10:47:17 +00:00
bors[bot] c1a022385f
Merge #1086
1086: Slice support r=philberty a=philberty

Please see the commit a8de089969cb45199008027cd8d1b80dff25746f for
a long explanation of what's going on in the patch. Unfortunately, I have not been
able to split this patch up anymore since supporting slices exposed many bugs
in the implementation of generics in general never main the missing support for
generic associated types.

Fixes #849 

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
2022-04-12 09:50:56 +00:00
liushuyu 2fe4048f7f
macros: fix an infinite loop ...
... introduced in fed5a41fb1, should fix #1102

Signed-off-by: Zixing Liu <liushuyu011@gmail.com>
2022-04-12 02:18:56 -06:00
liushuyu e909e4fc7b
testsuite/rust: add a xfail test case ...
... to show case the timeout system is working
2022-04-11 17:11:50 -06:00
liushuyu 997894f637
testsuite/rust: add a 10-second timeout for each compile test 2022-04-11 17:11:13 -06:00
Philip Herron 0e686c0fe0 Support Slices from rustc libcore 1.49.0
This is unfortunatly a mega commit, in testing gccrs against the slice code
which is highly generic stress tested our implementation of generics and
poked the hole in or lack of support of generic higher ranked trait bounds
and more specificily generic associated types. More refactoring is needed
to eventually remove the setup_associated_types and replace it entirely
with this new setup_associated_types2 which takes into account the trait
bound receiver and its predicate.

In order to support slices, the code in libcore defines an index lang item

```rust
impl<T, I> Index<I> for [T]
where
    I: SliceIndex<[T]>,
{
    type Output = I::Output;

    fn index(&self, index: I) -> &I::Output {
        index.index(self)
    }
}
```

This is the entry point where by the self here is a generic slice. So in
our case we have:

```rust
let a = [1, 2, 3, 4, 5];
let b = &a[1..3];
```

'a' is an array and b is our desired slice, so we must remember that from
algebraic data type constructor. But our receiver is still an array, so in
order to be able to call this index lang item we must 'unsize' our array
(see #1045) this allows for method resolution to adjust an array into a
FatPtr which is simply a struct containing reference to the array and the
capacity (GCC MAX_DOMAIN) of the underlying array data type. So now we are
able to infer the substituions for this index fn call to:

```
fn index(&self : [<integer>], index: Range<integer>)
  -> &I::Output->placeholder
```

The complex piece here is the Higher ranked trait bound:

```
where I: SliceIndex<[T]>
```

So in this method call no generic arguments are specified so we must try
and infer the types. So during monomorphization the inference variables
need to be recursively propogated into the higher ranked trait bound. So
that the higher ranked trait bound looks like:

```
SliceIndex<[<integer>]> // like we seen earlier for the Self type
```

The monomorphization stage also needs to take into account the higher
ranked trait bound's type which is 'I' and infered to be: Range<integer>.
This is where specialization needs to occur.

```rust
unsafe impl<T> SliceIndex<[T]> for Range<usize> {
    type Output = [T];

    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
        unsafe {
            let a: *const T = slice.as_ptr();
            let b: *const T = a.add(self.start);
            slice_from_raw_parts(b, self.end - self.start)
        }
    }

    fn index(self, slice: &[T]) -> &[T] {
        unsafe { &*self.get_unchecked(slice) }
    }
}
```

So now we need to compute the constrained type-parameters for this
specialized impl block. And in this case is fairly simple:

```
  impl<T> SliceIndex<[T]> for Range<usize>
  vs
  I: SliceIndex<[<integer>]> and Range<<integer>>
```

Here we need to compute that T is <integer>, which is required since
associated type Output is used in our original method call and this
is generic which requires us to set it up but both the Self type or
the trait bound here in this impl block could be generic so special
care needs to be taken to compute this safely. Once the constrained
types are computer we can also unify the Self types which specializes
our original Range<integer> type into the correct Range<usize> that
this trait bound expects. We used a callback here when we reusively
pass down the SubstitutionArgumentMappings when any Parameter type
is substitued we get a callback to hold a set of mappings in a generic
way what generic types are being substituted.

From all of this work this stressed our generics implementation to
breaking point due to the use of the generic trait bound which was
not supported and it also exposed many bugs in our implementation.
This is why I feel it is best to keep this a large patch as so much
of this patch will cause regressions if we don't keep it together.

One of the main changes we have made is how we handle parameters
substitution for example we might have a generic such as '&Y' but
this gets substituted with Y=T which is a new type parameter. Before
we used to directly just change this from &Y to &T which is correct
but this looses context from the generic argument bindings. So now
we maintain the information that &Y changes to &(Y=T) so that we see
Y was substutued with T so that subsequent substitutions or inferences
can change Y=?T and correctly map &Y to &(Y=T) to &(Y=?T).

The other major piece which was changed during this patch was how
we perform the method resolution on higher ranked trait bound calls
where we compute the specified bound possible candidates once so that
in the case:

```
trait Bar {
  fn baz(&self)
}

fn <T:Bar> foo(a: &T) {
  a.baz()
}
```

Here the type parameter T gets derefed to find the specified bound of
Bar which contains the method baz. This means that we try calling baz
with T vs &T which fails then we try the reference type T again. This
results into two useless adjustments of indirection and referencing but
GCC optimizes this away. Before this patch we computed the specified bound
for each attempt which was wrong.

Fixes #849
2022-04-11 16:37:28 +01:00
Arthur Cohen 9f5d8a8973 ast: Translate visibilities properly when lowering AST nodes
Previously, the lowering code would simply create public
`HIR::Visibility`s for every AST Node being lowered. We now call
`translate_visibility()` properly to perform the necessary conversions
2022-04-11 17:18:02 +02:00
Arthur Cohen 7d806eba2b ast: lowering: Add translate_visibility() static function
This function desugars `AST::Visibility`s into `HIR::Visibility`s,
performing all the necessary checks and conversions
2022-04-11 17:18:02 +02:00
Arthur Cohen 2a264a3693 hir: Cleanup Visibility struct
The HIR::Visibility struct was extremely similar to the AST::Visibility
one. However, we do not need to keep as much information at the HIR
level: Syntactic sugar such as pub(crate) can be kept as the desugared
form, which is pub(in crate). Likewise, pub(self) can be desugared to
pub(in self) which amounts to having a private item.
2022-04-11 17:18:02 +02:00
Philip Herron 69d6fddcbb Allow substitutions to be handled on primitive types without causing unreachable 2022-04-11 11:44:59 +01:00
Philip Herron 0e7eef6556 Make the can equal interface more permissive with associated types 2022-04-11 11:44:59 +01:00
Philip Herron e7e6527975 Add missing const for get_locus and helper to get used arguments 2022-04-11 11:44:59 +01:00
Philip Herron 68458036c8 Disable failing testcase
This commit fed5a41fb1 introduced the concat
builtin macro but the error handling here is producing an infinite loop
which was not caught during code-review. This patch disables the offending
error cases so that it does not impact further development.

Addresses #1102
2022-04-11 11:31:14 +01:00
bors[bot] 1b8d4521db
Merge #1091
1091: Add -frust-edition flag and possible values r=CohenArthur a=CohenArthur

Closes #1072 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-04-11 09:41:23 +00:00
bors[bot] 2669e80c17
Merge #1090 #1097 #1098 #1099 #1101
1090: macros: add concat! macro r=philberty a=liushuyu

- extracts parenthesis-matching logic into a function
- adds `concat!` macro

1097: Support mangling *const ptr and slices like *const [T] r=philberty a=philberty

The legacy mangling scheme needs to convert the canonical path containing
* for pointers and the [] brackets representing slices into:

  * = $BP$
  [ = $u5b$
  ] = $u5d$

These symbols are not allowed in asm symbols.

Addresses #849


1098: Ensure unsize method resolutions actually unsize r=philberty a=philberty

This was a typo when unsized method resolution was added, where the
adjustment was wrongly marked as an indirection. The enum is required so
that the code generation adjustment takes place.

Addresses #849

1099: Fix bad inherent overlap error r=philberty a=philberty

When we examine HIR::ImplBlock's we determine if an impl might overlap
another impl based on the Self type. So for example you might have a
generic structure Foo<T>(T), and an associated impl block for Foo<i32>, but
then go on to define an associated impl of Foo<T> the generic one will
overlap any associated impl hiding the generic implementation.

In this case we have two generic impl blocks

  *const [T]
  *const T

This means the *const T might overlap with the slice one since it is
generic. As bjorn3 pointed out in #1075 , the correct implementation is to
observe that [T] is constrained by size but untill we have the auto trait
of Sized we must example the two generic impls and just determine that
they are not-equal so for now this is the best implementation we can do.

Fixes #1075 


1101: Add helper as_string for DefIds r=philberty a=philberty

This just adds a useful helper to as_string DefId's directly

Co-authored-by: liushuyu <liushuyu011@gmail.com>
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
2022-04-11 09:10:22 +00:00
Philip Herron 3513fa38f2
Update gcc/rust/util/rust-mapping-common.h
Co-authored-by: CohenArthur <arthur.cohen@embecosm.com>
2022-04-11 09:56:14 +01:00
Philip Herron 4413bc0cf8 Fix bad inherent overlap error
When we examine HIR::ImplBlock's we determine if an impl might overlap
another impl based on the Self type. So for example you might have a
generic structure Foo<T>(T), and an associated impl block for Foo<i32>, but
then go on to define an associated impl of Foo<T> the generic one will
overlap any associated impl hiding the generic implementation.

In this case we have two generic impl blocks

  *const [T]
  *const T

This means the *const T might overlap with the slice one since it is
generic. As bjorn3 pointed out in #1075, the correct implementation is to
observe that [T] is constrained by size but untill we have the auto trait
of Sized we must example the two generic impls and just determine that
they are not-equal so for now this is the best implementation we can do.

Fixes #1075
2022-04-11 09:47:22 +01:00
bors[bot] e5281ee490
Merge #1100
1100: Add known lang item const_slice_ptr mappings r=philberty a=philberty

This will allow us to define the const_slice_ptr lang item attribute
without erroring out as an unknown lang item.

Addresses #849 

Co-authored-by: Philip Herron <philip.herron@embecosm.com>
2022-04-11 08:43:48 +00:00
liushuyu fed5a41fb1
macros: add concat! macro
Signed-off-by: Zixing Liu <liushuyu011@gmail.com>
2022-04-11 02:31:17 -06:00
Philip Herron b1f42c38f5 Add helper as_string for DefIds 2022-04-09 22:26:42 +01:00
Philip Herron 595eb9c411 Add known lang item const_slice_ptr mappings
This will allow us to define the const_slice_ptr lang item attribute
without erroring out as an unknown lang item.
2022-04-09 22:17:39 +01:00
Philip Herron 8d3184e822 Ensure unsize method resolutions actually unsize
This was a typo when unsized method resolution was added, where the
adjustment was wrongly marked as an indirection. The enum is required so
that the code generation adjustment takes place.

Addresses #849
2022-04-09 21:56:46 +01:00
Philip Herron 6fb118f3e2 Support mangling *const ptr and slices like *const [T]
The legacy mangling scheme needs to convert the canonical path containing
* for pointers and the [] brackets representing slices into:

  * = $BP$
  [ = $u5b$
  ] = $u5d$

These symbols are not allowed in asm symbols.

Addresses #849
2022-04-09 21:53:06 +01:00
bors[bot] e43a5c5373
Merge #1092
1092: gcc/rust/Make-lang.in: add missing rust compiler driver r=philberty a=RomainNaour

When building gccrs with Buildroot toolchain infrastructure, the gccrs
compiler driver is missing when intalling gcc.

This is due to missing depedency on gccrs$(exeext) in rust.all.cross
target.

With that fixed, the gcc toolchain with Rust support is correctly installed into Buildroot:

$ ./test/gccrs/host/bin/aarch64-linux-gccrs --version
aarch64-linux-gccrs (Buildroot 2022.02-442-g54d638fbd1-dirty) 12.0.1 20220118 (experimental)

Note: We probably needs gccrs-cross target like other supported languages.

Copyright assignment signed between Smile and the FSF to contribute to GNU tools.

Co-authored-by: Romain Naour <romain.naour@smile.fr>
2022-04-08 09:11:01 +00:00
Arthur Cohen 46e0068fc0 options: Add -frust-edition flag and possible values
Co-authored-by: liushuyu <liushuyu011@gmail.com>
2022-04-08 11:09:13 +02:00
bors[bot] da3d59db1f
Merge #1087
1087: Use loop to initialize repeat arrays r=philberty a=dafaust

This PR changes how we compile initializers for arrays of repeating elements. I use the same approach outlined in the comments of the linked issue, with some tweaks. It is very similar to how the D language front-end compiles, the new function `Gcc_backend::array_initializer` is heavily inspired by the D front-end's `build_array_set`

This fixes the issue where the compiler tries to allocate a vec containing all elements of the array to be constructed, and therefore explodes on huge constructions (e.g. `let x = [0u8; 4 * 1024 * 1024 * 1024 * 1024]`)

However, we can only initialize non-const arrays in this way. For arrays in const contexts we must initialize them at compile time, and therefore continue using the old method.

Fixes: #1068 


Co-authored-by: David Faust <david.faust@oracle.com>
2022-04-08 08:30:30 +00:00
Romain Naour 83681c3990 gcc/rust/Make-lang.in: add missing rust compiler driver
When building gccrs with Buildroot toolchain infrastructure, the gccrs
compiler driver is missing when intalling gcc.

This is due to missing depedency on gccrs$(exeext) in rust.all.cross
target.

Signed-off-by: Romain Naour <romain.naour@smile.fr>
---
We probably needs gccrs-cross target like other supported languages.
2022-04-08 09:28:23 +02:00
David Faust 5559bdc866 Emit loop initializer for repeat arrays
This commit changes how arrays of repeating elements, e.g. [5; 12] are
compiled. Rather than create a constructor which explicitly initializes
each element to the given value (which causes compiler OOM for large
arrays), we emit instructions to allocate the array then initialize the
elements in a loop.

However, we can only take this approach outside of const contexts -
const arrays must still use the old approach.
2022-04-07 09:57:46 -07:00
bors[bot] b829e7c0a2
Merge #1080
1080: macros: add compile_error! macro r=CohenArthur a=liushuyu

- Added `compile_error` macro


Co-authored-by: liushuyu <liushuyu011@gmail.com>
2022-04-07 08:16:07 +00:00
bors[bot] 779de323f3
Merge #1083
1083: bugfix: fix several minor issues r=CohenArthur a=liushuyu

- Fixed `-frust-crate= option` got incorrectly overridden by a default value (`example`)
- Fix a minor typo in `gcc/rust/ast/rust-ast-full-test.cc`

Co-authored-by: liushuyu <liushuyu011@gmail.com>
2022-04-06 11:00:42 +00:00
liushuyu af14ad6056
rust-ast-full-test: fix a minor typo
Signed-off-by: Zixing Liu <liushuyu011@gmail.com>
2022-04-05 17:46:29 -06:00
liushuyu 6d42548da9
rust-session-manager: fix an issue where ...
... the -frust-crate= option got incorrectly overridden by a default
value

Signed-off-by: Zixing Liu <liushuyu011@gmail.com>
2022-04-05 17:46:19 -06:00
liushuyu 35570ae410
macros: add compile_error! macro
addresses #927

Signed-off-by: Zixing Liu <liushuyu011@gmail.com>
2022-04-03 17:17:33 -06:00
bors[bot] 9011184f38
Merge #1071
1071: Allow transcribing of zero nodes in certain cases r=CohenArthur a=CohenArthur

When expanding AST fragments containing multiple nodes, we must be aware
that some cases allow expanding zero or more nodes. Any macro
transcription that gets parsed as many nodes (ie any transcriber function that calls `parse_many`) needs to be able to parse zero of those nodes and still get expanded properly (basically, removed).

Previously, this would cause a failure to lower the macro invocation which would remain as a child instead of getting stripped/erased.



Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-31 09:56:35 +00:00
Arthur Cohen 73532817fd macros: Allow transcribing of zero items
When expanding AST fragments containing multiple nodes, we must be aware
that some cases allow expanding zero or more nodes. Any macro
transcription that gets parsed as many nodes (ie any transcriber function that calls `parse_many`) needs to be able to parse zero of those nodes and still get expanded properly (basically, removed).

Previously, this would cause a failure to lower the macro invocation which would remain as a child instead of getting stripped/erased.

Co-authored-by: philberty <philip.herron@embecosm.com>
2022-03-31 11:32:26 +02:00
bors[bot] f9c1a14dab
Merge #1069
1069: Handle macro invocations in type contexts r=CohenArthur a=CohenArthur

Closes #1067 

This highlighted two issues where parsing types is not entirely correct, which I'll raise. The code necessary to handle macro invocations in these two places should already be implemented. 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-31 08:28:42 +00:00
Arthur Cohen 6bf428379d macros: Expand macro invocation properly in type contexts
Macro invocations can be present where the language expects types. Thus,
we need to add a new type of parsing context, a new transcriber, as well
as a new way to extract types from the AST Fragments. This adds a lot of
"expansion places" in the attribute visitor, as types can be present in
a wide variety of constructs
2022-03-31 09:42:26 +02:00
Arthur Cohen 3413f632ec ast_fragment: Add take_type_fragment() method
Co-authored-by: philberty <philip.herron@embecosm.com>
2022-03-31 09:42:26 +02:00
Arthur Cohen b6bbf1fa72 macro_transcriber: Add TYPE context and associated transcriber 2022-03-31 09:42:08 +02:00
Arthur Cohen 229512d662 single_ast_node: Fix typo in as_string() method 2022-03-31 09:42:08 +02:00
Arthur Cohen cf94fd8d51 single_ast_node: Add TYPE kind 2022-03-31 09:42:08 +02:00
bors[bot] bd1f435b23
Merge #1059
1059: Add base for build job using older GCC version r=CohenArthur a=CohenArthur

Fixes #1058 

Co-authored-by: Arthur Cohen <arthur.cohen@embecosm.com>
2022-03-30 11:14:40 +00:00
Arthur Cohen e824a0835b ci: Run tests with gccrs compiled under gcc-4.8 2022-03-29 10:22:53 +02:00
bors[bot] e8b9587d3a
Merge #1045
1045: Add initial support for unsized method resolution r=philberty a=philberty

In order to support slices, we end up with an operator overload call of:

```
impl<T, I> Index<I> for [T]
where
    I: SliceIndex<[T]>,
{
    type Output = I::Output;

    fn index(&self, index: I) -> &I::Output {
        index.index(self)
    }
}
```

So this means the self, in this case, is an array[T,capacity] and the index parameter is of type Range<usize>. In order to actually call this method
which has a self parameter of [T] we need to be able to 'unsize' the array
into a slice.

Addresses #849


Co-authored-by: Philip Herron <philip.herron@embecosm.com>
2022-03-28 14:22:24 +00:00