diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-30 16:16:38 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-30 16:16:38 +0000 |
commit | b1dcbc3d8e2fedd7b0c2f42554f4c2297469dabe (patch) | |
tree | 6ac4d268325bf75dfc747c12ff18122826a5c151 /gcc | |
parent | 0276ec39a9c3b839c47ce28838a8d5af25fbf598 (diff) | |
parent | 2216cab0c9f694016d6cc220cfa8f5c23ba5f465 (diff) | |
download | gcc-b1dcbc3d8e2fedd7b0c2f42554f4c2297469dabe.zip gcc-b1dcbc3d8e2fedd7b0c2f42554f4c2297469dabe.tar.gz gcc-b1dcbc3d8e2fedd7b0c2f42554f4c2297469dabe.tar.bz2 |
Merge #401
401: Add defaults support for generics r=philberty a=philberty
This adds in the basic support for default arguments for generics such as:
```rust
struct Foo<A,B=f32>(A,B);
```
or recursive type params such as:
```rust
struct Foo<A, B = (A, A)>(A, B);
```
Fixes #307
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/hir/rust-ast-lower-item.h | 23 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 12 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 14 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compile/generics25.rs | 9 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/xfail_compile/generics10.rs | 12 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/xfail_compile/generics9.rs | 11 |
6 files changed, 75 insertions, 6 deletions
diff --git a/gcc/rust/hir/rust-ast-lower-item.h b/gcc/rust/hir/rust-ast-lower-item.h index 18ead3c..fe0b791 100644 --- a/gcc/rust/hir/rust-ast-lower-item.h +++ b/gcc/rust/hir/rust-ast-lower-item.h @@ -349,6 +349,29 @@ public: { generic_params = lower_generic_params (impl_block.get_generic_params ()); + + for (auto &generic_param : generic_params) + { + switch (generic_param->get_kind ()) + { + case HIR::GenericParam::GenericKind::TYPE: { + const HIR::TypeParam &t + = static_cast<const HIR::TypeParam &> (*generic_param); + + if (t.has_type ()) + { + // see https://github.com/rust-lang/rust/issues/36887 + rust_error_at ( + t.get_locus (), + "defaults for type parameters are not allowed here"); + } + } + break; + + default: + break; + } + } } HIR::Type *trait_type diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index d249c43..a1dcb4c 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -262,6 +262,12 @@ public: { ok = true; + // if it has a type lets resolve it + if (param.has_type ()) + { + ResolveType::go (param.get_type ().get (), param.get_node_id ()); + } + // for now lets focus on handling the basics: like struct<T> { a:T, ....} resolver->get_type_scope ().insert ( CanonicalPath (param.get_type_representation ()), param.get_node_id (), @@ -271,12 +277,6 @@ public: "generic param redefined multiple times"); rust_error_at (locus, "was defined here"); }); - - // if it has a type lets resolve it - if (param.has_type ()) - { - ResolveType::go (param.get_type ().get (), param.get_node_id ()); - } } private: diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc index 3e9098d..f5daf3a 100644 --- a/gcc/rust/typecheck/rust-tyty.cc +++ b/gcc/rust/typecheck/rust-tyty.cc @@ -271,6 +271,20 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args) rust_assert (param.param_has_default_ty ()); BaseType *resolved = param.get_default_ty (); + if (resolved->get_kind () == TypeKind::ERROR) + return SubstitutionArgumentMappings::error (); + + // this resolved default might already contain default parameters + if (resolved->contains_type_parameters ()) + { + SubstitutionArgumentMappings intermediate (mappings, + args.get_locus ()); + resolved = Resolver::SubstMapperInternal::Resolve (resolved, + intermediate); + if (resolved->get_kind () == TypeKind::ERROR) + return SubstitutionArgumentMappings::error (); + } + SubstitutionArg subst_arg (¶m, resolved); mappings.push_back (std::move (subst_arg)); } diff --git a/gcc/testsuite/rust.test/compile/generics25.rs b/gcc/testsuite/rust.test/compile/generics25.rs new file mode 100644 index 0000000..e7792e3 --- /dev/null +++ b/gcc/testsuite/rust.test/compile/generics25.rs @@ -0,0 +1,9 @@ +struct Foo<A, B = (A, A)>(A, B); + +fn main() { + let a: Foo<bool>; + a = Foo::<bool>(true, (false, true)); + + let b: (bool, bool); + b = a.1; +} diff --git a/gcc/testsuite/rust.test/xfail_compile/generics10.rs b/gcc/testsuite/rust.test/xfail_compile/generics10.rs new file mode 100644 index 0000000..a734fa8 --- /dev/null +++ b/gcc/testsuite/rust.test/xfail_compile/generics10.rs @@ -0,0 +1,12 @@ +struct Foo<A, B>(A, B); + +impl<X = i32> Foo<X, f32> { // { dg-error "defaults for type parameters are not allowed here" } + fn new(a: X, b: f32) -> Self { + Self(a, b) + } +} + +fn main() { + let a; + a = Foo::new(123, 456f32); +} diff --git a/gcc/testsuite/rust.test/xfail_compile/generics9.rs b/gcc/testsuite/rust.test/xfail_compile/generics9.rs new file mode 100644 index 0000000..c1ff89b --- /dev/null +++ b/gcc/testsuite/rust.test/xfail_compile/generics9.rs @@ -0,0 +1,11 @@ +// { dg-excess-errors "Noisy error and debug" } +struct Foo<A, B = (A, B)>(A, B); +// { dg-error "failed to resolve TypePath: B" "" { target { *-*-* } } .-1 } + +fn main() { + let a: Foo<bool>; + a = Foo::<bool>(true, (false, true)); + + let b: (bool, bool); + b = a.1; +} |