diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.cc | 27 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-path.cc | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-type.cc | 89 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-2165.rs | 9 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-2166.rs | 23 |
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 + } +} |