aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2023-06-12 16:07:13 +0100
committerPhilip Herron <philip.herron@embecosm.com>2023-06-13 08:46:22 +0000
commite43261892fb74f30639302eaff3eee6f626cc384 (patch)
tree836018b58c26e09b2bbbb9b71ab5b9b2604ca739
parente3e945f055f2d2dd972e20380c2df69a62912be7 (diff)
downloadgcc-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.cc17
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-reference.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-trait-resolve.cc30
-rw-r--r--gcc/testsuite/rust/compile/issue-2019-1.rs22
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)
+ }
+}