public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Arthur Cohen <cohenarthur@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-7646] gccrs: Respect the concrete type when resolving qualifed path types Date: Tue, 16 Jan 2024 17:50:15 +0000 (GMT) [thread overview] Message-ID: <20240116175015.91377385841C@sourceware.org> (raw) https://gcc.gnu.org/g:e64a12f903bd64437bc9267f27dc2ba59b6ad5d5 commit r14-7646-ge64a12f903bd64437bc9267f27dc2ba59b6ad5d5 Author: Philip Herron <herron.philip@googlemail.com> Date: Wed May 31 16:06:58 2023 +0100 gccrs: Respect the concrete type when resolving qualifed path types Concrete types can resolve to assoicated impl blocks which will allow us to resolve the path to the projection type instead of the placeholder trait associated type which can change. The projection will be fixed and is safer to use. Fixes #2165 #2166 gcc/rust/ChangeLog: * typecheck/rust-hir-trait-resolve.cc: when the bound is concrete keep the mapping * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::visit): add missing call * typecheck/rust-hir-type-check-type.cc (TypeCheckType::visit): make this the same as paths gcc/testsuite/ChangeLog: * rust/compile/issue-2165.rs: New test. * rust/compile/issue-2166.rs: New test. Signed-off-by: Philip Herron <herron.philip@googlemail.com> Diff: --- gcc/rust/typecheck/rust-hir-trait-resolve.cc | 27 ++++---- gcc/rust/typecheck/rust-hir-type-check-path.cc | 2 + gcc/rust/typecheck/rust-hir-type-check-type.cc | 89 +++++++++++++++----------- gcc/testsuite/rust/compile/issue-2165.rs | 9 +++ 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 37d4239fc0c..cf8c9c97807 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 a52a4e4397a..6ae58cea631 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 41c444029b6..0675c491a93 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 00000000000..199bc13aa68 --- /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 00000000000..f333888879a --- /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 + } +}
reply other threads:[~2024-01-16 17:50 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240116175015.91377385841C@sourceware.org \ --to=cohenarthur@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).