[gcc r14-7669] gccrs: ensure assoicated types are setup for concrete trait impl blocks

Arthur Cohen cohenarthur@gcc.gnu.org
Tue Jan 16 17:52:14 GMT 2024


https://gcc.gnu.org/g:73a2f1b4d64dcef17aa26a82a6cddc41ad8c87ff

commit r14-7669-g73a2f1b4d64dcef17aa26a82a6cddc41ad8c87ff
Author: Philip Herron <herron.philip@googlemail.com>
Date:   Mon Jun 12 16:07:13 2023 +0100

    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>

Diff:
---
 gcc/rust/backend/rust-compile-item.cc         | 17 +++++++++++++++
 gcc/rust/typecheck/rust-hir-trait-reference.h |  2 ++
 gcc/rust/typecheck/rust-hir-trait-resolve.cc  | 30 +++++++++++++++++++++++++++
 gcc/testsuite/rust/compile/issue-2019-1.rs    | 22 ++++++++++++++++++++
 4 files changed, 71 insertions(+)

diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc
index 26f56c70886..b83ef56788b 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 76d2d8bae83..c0a6f561ada 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 cf8c9c97807..7c6ce4c7a2d 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 00000000000..f359ea4fb15
--- /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)
+    }
+}


More information about the Gcc-cvs mailing list