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/rust | |
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/rust')
-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 |
3 files changed, 43 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)); } |