Skip to content

Commit feaafdf

Browse files
committedApr 30, 2021
Apply defaults if available to type substitutions
When we get defaults specified to Type parameters we must resolve the type before insert the name into the name scope otherwise we can end up with forward declared type parameters being resolved. When we need to apply defaults during substitution we must check if they themseleves need substitutions also with the mappings we have generated so far. Fixes #307
1 parent 0276ec3 commit feaafdf

File tree

4 files changed

+40
-6
lines changed

4 files changed

+40
-6
lines changed
 

‎gcc/rust/resolve/rust-ast-resolve-type.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@ class ResolveGenericParam : public ResolverBase
262262
{
263263
ok = true;
264264

265+
// if it has a type lets resolve it
266+
if (param.has_type ())
267+
{
268+
ResolveType::go (param.get_type ().get (), param.get_node_id ());
269+
}
270+
265271
// for now lets focus on handling the basics: like struct<T> { a:T, ....}
266272
resolver->get_type_scope ().insert (
267273
CanonicalPath (param.get_type_representation ()), param.get_node_id (),
@@ -271,12 +277,6 @@ class ResolveGenericParam : public ResolverBase
271277
"generic param redefined multiple times");
272278
rust_error_at (locus, "was defined here");
273279
});
274-
275-
// if it has a type lets resolve it
276-
if (param.has_type ())
277-
{
278-
ResolveType::go (param.get_type ().get (), param.get_node_id ());
279-
}
280280
}
281281

282282
private:

‎gcc/rust/typecheck/rust-tyty.cc

+14
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,20 @@ SubstitutionRef::get_mappings_from_generic_args (HIR::GenericArgs &args)
271271
rust_assert (param.param_has_default_ty ());
272272

273273
BaseType *resolved = param.get_default_ty ();
274+
if (resolved->get_kind () == TypeKind::ERROR)
275+
return SubstitutionArgumentMappings::error ();
276+
277+
// this resolved default might already contain default parameters
278+
if (resolved->contains_type_parameters ())
279+
{
280+
SubstitutionArgumentMappings intermediate (mappings,
281+
args.get_locus ());
282+
resolved = Resolver::SubstMapperInternal::Resolve (resolved,
283+
intermediate);
284+
if (resolved->get_kind () == TypeKind::ERROR)
285+
return SubstitutionArgumentMappings::error ();
286+
}
287+
274288
SubstitutionArg subst_arg (&param, resolved);
275289
mappings.push_back (std::move (subst_arg));
276290
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
struct Foo<A, B = (A, A)>(A, B);
2+
3+
fn main() {
4+
let a: Foo<bool>;
5+
a = Foo::<bool>(true, (false, true));
6+
7+
let b: (bool, bool);
8+
b = a.1;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// { dg-excess-errors "Noisy error and debug" }
2+
struct Foo<A, B = (A, B)>(A, B);
3+
// { dg-error "failed to resolve TypePath: B" "" { target { *-*-* } } .-1 }
4+
5+
fn main() {
6+
let a: Foo<bool>;
7+
a = Foo::<bool>(true, (false, true));
8+
9+
let b: (bool, bool);
10+
b = a.1;
11+
}

0 commit comments

Comments
 (0)
Please sign in to comment.