diff options
author | Philip Herron <herron.philip@googlemail.com> | 2023-06-12 16:07:13 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2023-06-13 08:46:22 +0000 |
commit | e43261892fb74f30639302eaff3eee6f626cc384 (patch) | |
tree | 836018b58c26e09b2bbbb9b71ab5b9b2604ca739 | |
parent | e3e945f055f2d2dd972e20380c2df69a62912be7 (diff) | |
download | gcc-e43261892fb74f30639302eaff3eee6f626cc384.zip gcc-e43261892fb74f30639302eaff3eee6f626cc384.tar.gz gcc-e43261892fb74f30639302eaff3eee6f626cc384.tar.bz2 |
gccrs: ensure assoicated types are setup for concrete trait impl blocks
We have been concentrating on generic impl blocks for so long that we have
not handled the simple concrete impl block case where associated types need
to be setup when compling a function/method on a trait impl block which
uses associated types.
Addresses #2019
gcc/rust/ChangeLog:
* backend/rust-compile-item.cc (CompileItem::visit): ensure assoicated types are setup
* typecheck/rust-hir-trait-reference.h: new interface for concrete impl block
* typecheck/rust-hir-trait-resolve.cc (AssociatedImplTrait::setup_raw_associated_types):
ensure we setup assoicated types for this impl block
gcc/testsuite/ChangeLog:
* rust/compile/issue-2019-1.rs: New test.
Signed-off-by: Philip Herron <herron.philip@googlemail.com>
-rw-r--r-- | gcc/rust/backend/rust-compile-item.cc | 17 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-reference.h | 2 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-hir-trait-resolve.cc | 30 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/issue-2019-1.rs | 22 |
4 files changed, 71 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc index 4ba2956..4a01cf7 100644 --- a/gcc/rust/backend/rust-compile-item.cc +++ b/gcc/rust/backend/rust-compile-item.cc @@ -133,6 +133,23 @@ CompileItem::visit (HIR::Function &function) fntype->monomorphize (); } } + else + { + // if this is part of a trait impl block which is not generic we need to + // ensure associated types are setup + HirId parent_impl_block = UNKNOWN_HIRID; + HirId id = function.get_mappings ().get_hirid (); + HIR::ImplItem *impl_item + = ctx->get_mappings ()->lookup_hir_implitem (id, &parent_impl_block); + if (impl_item != nullptr) + { + Resolver::AssociatedImplTrait *impl = nullptr; + bool found = ctx->get_tyctx ()->lookup_associated_trait_impl ( + parent_impl_block, &impl); + if (found) + impl->setup_raw_associated_types (); + } + } const Resolver::CanonicalPath *canonical_path = nullptr; bool ok = ctx->get_mappings ()->lookup_canonical_path ( diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h index 8062406..91621a2 100644 --- a/gcc/rust/typecheck/rust-hir-trait-reference.h +++ b/gcc/rust/typecheck/rust-hir-trait-reference.h @@ -249,6 +249,8 @@ public: TyTy::BaseType *get_self (); const TyTy::BaseType *get_self () const; + void setup_raw_associated_types (); + TyTy::BaseType * setup_associated_types (const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound); diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index 77411dc..d7eb16d 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -400,6 +400,36 @@ TraitItemReference::associated_type_reset (bool only_projections) const } } +void +AssociatedImplTrait::setup_raw_associated_types () +{ + auto &impl_items = impl->get_impl_items (); + for (auto &impl_item : impl_items) + { + bool is_type_alias = impl_item->get_impl_item_type () + == HIR::ImplItem::ImplItemType::TYPE_ALIAS; + if (!is_type_alias) + continue; + + HIR::TypeAlias &type = *static_cast<HIR::TypeAlias *> (impl_item.get ()); + + TraitItemReference *resolved_trait_item = nullptr; + bool ok = trait->lookup_trait_item (type.get_new_type_name (), + &resolved_trait_item); + if (!ok) + continue; + if (resolved_trait_item->get_trait_item_type () + != TraitItemReference::TraitItemType::TYPE) + continue; + + TyTy::BaseType *lookup; + ok = context->lookup_type (type.get_mappings ().get_hirid (), &lookup); + rust_assert (ok); + + resolved_trait_item->associated_type_set (lookup); + } +} + TyTy::BaseType * AssociatedImplTrait::setup_associated_types ( const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound) diff --git a/gcc/testsuite/rust/compile/issue-2019-1.rs b/gcc/testsuite/rust/compile/issue-2019-1.rs new file mode 100644 index 0000000..f359ea4 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-2019-1.rs @@ -0,0 +1,22 @@ +#[lang = "add"] +pub trait Add<RHS = Self> { + type Output; + + fn add(self, rhs: RHS) -> Self::Output; +} + +impl Add for u32 { + type Output = u32; + + fn add(self, other: u32) -> u32 { + self + other + } +} + +impl<'a> Add<u32> for &'a u32 { + type Output = <u32 as Add<u32>>::Output; + + fn add(self, other: u32) -> <u32 as Add<u32>>::Output { + Add::add(*self, other) + } +} |