aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc27
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc89
-rw-r--r--gcc/testsuite/rust/compile/issue-2165.rs9
-rw-r--r--gcc/testsuite/rust/compile/issue-2166.rs23
5 files changed, 103 insertions, 47 deletions
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index a2c6a97..77411dc 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -415,7 +415,10 @@ AssociatedImplTrait::setup_associated_types (
// we need to figure out what Y is
TyTy::BaseType *associated_self = get_self ();
- rust_assert (associated_self->can_eq (self, false));
+
+ rust_debug ("setup_associated_types for: %s->%s bound %s",
+ associated_self->debug_str ().c_str (),
+ self->debug_str ().c_str (), bound.as_string ().c_str ());
// grab the parameters
HIR::ImplBlock &impl_block = *get_impl_block ();
@@ -445,6 +448,14 @@ AssociatedImplTrait::setup_associated_types (
}
}
+ // this callback gives us the parameters that get substituted so we can
+ // compute the constrained type parameters for this impl block
+ std::map<std::string, HirId> param_mappings;
+ TyTy::ParamSubstCb param_subst_cb
+ = [&] (const TyTy::ParamType &p, const TyTy::SubstitutionArg &a) {
+ param_mappings[p.get_symbol ()] = a.get_tyty ()->get_ref ();
+ };
+
// generate inference variables for these bound arguments so we can compute
// their values
Location locus;
@@ -458,19 +469,13 @@ AssociatedImplTrait::setup_associated_types (
}
else
{
- args.push_back (
- TyTy::SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
+ TyTy::ParamType *param = p.get_param_ty ();
+ TyTy::BaseType *resolved = param->destructure ();
+ args.push_back (TyTy::SubstitutionArg (&p, resolved));
+ param_mappings[param->get_symbol ()] = resolved->get_ref ();
}
}
- // this callback gives us the parameters that get substituted so we can
- // compute the constrained type parameters for this impl block
- std::map<std::string, HirId> param_mappings;
- TyTy::ParamSubstCb param_subst_cb
- = [&] (const TyTy::ParamType &p, const TyTy::SubstitutionArg &a) {
- param_mappings[p.get_symbol ()] = a.get_tyty ()->get_ref ();
- };
-
TyTy::SubstitutionArgumentMappings infer_arguments (std::move (args), {},
locus, param_subst_cb);
TyTy::BaseType *impl_self_infer
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 02821fc..a62ebcb 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -89,6 +89,8 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
= lookup_associated_impl_block (specified_bound, root);
if (associated_impl_trait != nullptr)
{
+ associated_impl_trait->setup_associated_types (root, specified_bound);
+
for (auto &i :
associated_impl_trait->get_impl_block ()->get_impl_items ())
{
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 0170a5a..0cdac6e 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -178,8 +178,8 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
}
// Resolve the trait now
- TraitReference *trait_ref
- = TraitResolver::Resolve (*qual_path_type.get_trait ().get ());
+ std::unique_ptr<HIR::TypePath> &trait_path_ref = qual_path_type.get_trait ();
+ TraitReference *trait_ref = TraitResolver::Resolve (*trait_path_ref.get ());
if (trait_ref->is_error ())
return;
@@ -201,36 +201,6 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
// inherit the bound
root->inherit_bounds ({specified_bound});
- // setup the associated types
- const TraitReference *specified_bound_ref = specified_bound.get ();
- auto candidates = TypeBoundsProbe::Probe (root);
- AssociatedImplTrait *associated_impl_trait = nullptr;
- for (auto &probed_bound : candidates)
- {
- const TraitReference *bound_trait_ref = probed_bound.first;
- const HIR::ImplBlock *associated_impl = probed_bound.second;
-
- HirId impl_block_id = associated_impl->get_mappings ().get_hirid ();
- AssociatedImplTrait *associated = nullptr;
- bool found_impl_trait
- = context->lookup_associated_trait_impl (impl_block_id, &associated);
- if (found_impl_trait)
- {
- bool found_trait = specified_bound_ref->is_equal (*bound_trait_ref);
- bool found_self = associated->get_self ()->can_eq (root, false);
- if (found_trait && found_self)
- {
- associated_impl_trait = associated;
- break;
- }
- }
- }
-
- if (associated_impl_trait != nullptr)
- {
- associated_impl_trait->setup_associated_types (root, specified_bound);
- }
-
// lookup the associated item from the specified bound
std::unique_ptr<HIR::TypePathSegment> &item_seg
= path.get_associated_segment ();
@@ -243,8 +213,57 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
return;
}
- // infer the root type
- translated = item.get_tyty_for_receiver (root);
+ // we try to look for the real impl item if possible
+ HIR::ImplItem *impl_item = nullptr;
+ if (root->is_concrete ())
+ {
+ // lookup the associated impl trait for this if we can (it might be
+ // generic)
+ AssociatedImplTrait *associated_impl_trait
+ = lookup_associated_impl_block (specified_bound, root);
+ if (associated_impl_trait != nullptr)
+ {
+ associated_impl_trait->setup_associated_types (root, specified_bound);
+
+ for (auto &i :
+ associated_impl_trait->get_impl_block ()->get_impl_items ())
+ {
+ bool found = i->get_impl_item_name ().compare (
+ item_seg_identifier.as_string ())
+ == 0;
+ if (found)
+ {
+ impl_item = i.get ();
+ break;
+ }
+ }
+ }
+ }
+
+ NodeId root_resolved_node_id = UNKNOWN_NODEID;
+ if (impl_item == nullptr)
+ {
+ // this may be valid as there could be a default trait implementation here
+ // and we dont need to worry if the trait item is actually implemented or
+ // not because this will have already been validated as part of the trait
+ // impl block
+ translated = item.get_tyty_for_receiver (root);
+ root_resolved_node_id
+ = item.get_raw_item ()->get_mappings ().get_nodeid ();
+ }
+ else
+ {
+ HirId impl_item_id = impl_item->get_impl_mappings ().get_hirid ();
+ bool ok = query_type (impl_item_id, &translated);
+ if (!ok)
+ {
+ // FIXME
+ // I think query_type should error if required here anyway
+ return;
+ }
+
+ root_resolved_node_id = impl_item->get_impl_mappings ().get_nodeid ();
+ }
// turbo-fish segment path::<ty>
if (item_seg->get_type () == HIR::TypePathSegment::SegmentType::GENERIC)
@@ -270,8 +289,6 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
}
// continue on as a path-in-expression
- const TraitItemReference *trait_item_ref = item.get_raw_item ();
- NodeId root_resolved_node_id = trait_item_ref->get_mappings ().get_nodeid ();
bool fully_resolved = path.get_segments ().empty ();
if (fully_resolved)
{
diff --git a/gcc/testsuite/rust/compile/issue-2165.rs b/gcc/testsuite/rust/compile/issue-2165.rs
new file mode 100644
index 0000000..199bc13
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2165.rs
@@ -0,0 +1,9 @@
+pub trait Alpha<T = Self> {
+ type Beta;
+}
+
+impl Alpha for u32 {
+ type Beta = u32;
+}
+
+type Delta = <u32 as Alpha<u32>>::Beta;
diff --git a/gcc/testsuite/rust/compile/issue-2166.rs b/gcc/testsuite/rust/compile/issue-2166.rs
new file mode 100644
index 0000000..f333888
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2166.rs
@@ -0,0 +1,23 @@
+trait Add {
+ type Output;
+
+ fn add(self) -> u32;
+}
+
+impl Add for u32 {
+ type Output = u32;
+
+ fn add(self) -> u32 {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ 0
+ }
+}
+
+impl<'a> Add for &'a u32 {
+ type Output = u32;
+
+ fn add(self) -> <u32 as Add>::Output {
+ // { dg-warning "unused name" "" { target *-*-* } .-1 }
+ 0
+ }
+}