public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] gccrs: Remove monomorphization hack to setup possible associated types
@ 2023-02-07 17:56 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2023-02-07 17:56 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:edcf5b63bf60c1aec18df315fffbcd3d59d23119

commit edcf5b63bf60c1aec18df315fffbcd3d59d23119
Author: Philip Herron <herron.philip@googlemail.com>
Date:   Fri Jan 27 15:38:58 2023 +0000

    gccrs: Remove monomorphization hack to setup possible associated types
    
    During CallExpr argument type checking we may be calling a default
    implementation of a trait function this will require any possible
    associated types to be resolved and setup. This monomoprhization call does
    this but it will premtivly do extra unification of types which will throw
    off type checking later on. This fix is required for my work into type
    bounds checking.
    
    Fixes #1773
    
    Signed-off-by: Philip Herron <herron.philip@googlemail.com>
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-hir-trait-reference.h: change interface to return self
            * typecheck/rust-hir-trait-resolve.cc: likewise
            * typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): likewise
            * typecheck/rust-tyty-call.cc (TypeCheckCallExpr::visit): remove monomorphization hack
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-1773.rs: New test.

Diff:
---
 gcc/rust/typecheck/rust-hir-trait-reference.h  |  5 ++--
 gcc/rust/typecheck/rust-hir-trait-resolve.cc   | 10 +++----
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 36 ++++++++++++++++++++------
 gcc/rust/typecheck/rust-tyty-call.cc           |  1 -
 gcc/testsuite/rust/compile/issue-1773.rs       | 20 ++++++++++++++
 5 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h b/gcc/rust/typecheck/rust-hir-trait-reference.h
index d0814f60eaf..0d4da3b59cf 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.h
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.h
@@ -497,8 +497,9 @@ public:
 
   TyTy::BaseType *get_self () { return self; }
 
-  void setup_associated_types (const TyTy::BaseType *self,
-			       const TyTy::TypeBoundPredicate &bound);
+  TyTy::BaseType *
+  setup_associated_types (const TyTy::BaseType *self,
+			  const TyTy::TypeBoundPredicate &bound);
 
   void reset_associated_types ();
 
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index b293279a824..a7e073551f0 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -377,13 +377,10 @@ TraitItemReference::associated_type_reset () const
   placeholder->clear_associated_type ();
 }
 
-void
+TyTy::BaseType *
 AssociatedImplTrait::setup_associated_types (
   const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound)
 {
-  if (!bound.contains_associated_types ())
-    return;
-
   // compute the constrained impl block generic arguments based on self and the
   // higher ranked trait bound
   TyTy::BaseType *receiver = self->clone ();
@@ -486,6 +483,7 @@ AssociatedImplTrait::setup_associated_types (
     TyTy::TyWithLocation (receiver), TyTy::TyWithLocation (impl_self_infer),
     impl_predicate.get_locus ());
   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
+  TyTy::BaseType *self_result = result;
 
   // unify the bounds arguments
   std::vector<TyTy::BaseType *> hrtb_bound_arguments;
@@ -500,7 +498,7 @@ AssociatedImplTrait::setup_associated_types (
     }
 
   if (impl_trait_predicate_args.size () != hrtb_bound_arguments.size ())
-    return;
+    return self_result;
 
   for (size_t i = 0; i < impl_trait_predicate_args.size (); i++)
     {
@@ -554,6 +552,8 @@ AssociatedImplTrait::setup_associated_types (
     resolved_trait_item->associated_type_set (substituted);
   });
   iter.go ();
+
+  return self_result;
 }
 
 void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 4e765ad1380..1625eda373b 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -379,16 +379,36 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
 
       if (associated_impl_block != nullptr)
 	{
-	  // get the type of the parent Self
-	  HirId impl_ty_id
-	    = associated_impl_block->get_type ()->get_mappings ().get_hirid ();
+	  // associated types
+	  HirId impl_block_id
+	    = associated_impl_block->get_mappings ().get_hirid ();
+
+	  AssociatedImplTrait *associated = nullptr;
+	  bool found_impl_trait
+	    = context->lookup_associated_trait_impl (impl_block_id,
+						     &associated);
 	  TyTy::BaseType *impl_block_ty = nullptr;
-	  bool ok = query_type (impl_ty_id, &impl_block_ty);
-	  rust_assert (ok);
+	  if (found_impl_trait)
+	    {
+	      TyTy::TypeBoundPredicate predicate (*associated->get_trait (),
+						  seg.get_locus ());
+	      impl_block_ty
+		= associated->setup_associated_types (prev_segment, predicate);
+	    }
+	  else
+	    {
+	      // get the type of the parent Self
+	      HirId impl_ty_id = associated_impl_block->get_type ()
+				   ->get_mappings ()
+				   .get_hirid ();
 
-	  if (impl_block_ty->needs_generic_substitutions ())
-	    impl_block_ty
-	      = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+	      bool ok = query_type (impl_ty_id, &impl_block_ty);
+	      rust_assert (ok);
+
+	      if (impl_block_ty->needs_generic_substitutions ())
+		impl_block_ty
+		  = SubstMapper::InferSubst (impl_block_ty, seg.get_locus ());
+	    }
 
 	  prev_segment = unify_site (seg.get_mappings ().get_hirid (),
 				     TyTy::TyWithLocation (prev_segment),
diff --git a/gcc/rust/typecheck/rust-tyty-call.cc b/gcc/rust/typecheck/rust-tyty-call.cc
index 6334b69c87d..6ff0113e66b 100644
--- a/gcc/rust/typecheck/rust-tyty-call.cc
+++ b/gcc/rust/typecheck/rust-tyty-call.cc
@@ -85,7 +85,6 @@ TypeCheckCallExpr::visit (ADTType &type)
 void
 TypeCheckCallExpr::visit (FnType &type)
 {
-  type.monomorphize ();
   if (call.num_params () != type.num_params ())
     {
       if (type.is_varadic ())
diff --git a/gcc/testsuite/rust/compile/issue-1773.rs b/gcc/testsuite/rust/compile/issue-1773.rs
new file mode 100644
index 00000000000..c627ac09cec
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1773.rs
@@ -0,0 +1,20 @@
+trait Foo<T> {
+    type A;
+
+    fn test(a: Self::A) -> Self::A {
+        a
+    }
+}
+
+struct Bar<T>(T);
+impl<T> Foo<T> for Bar<i32> {
+    type A = T;
+}
+
+fn main() {
+    let a;
+    a = Bar(123);
+
+    let b;
+    b = Bar::test(a.0);
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-02-07 17:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-07 17:56 [gcc/devel/rust/master] gccrs: Remove monomorphization hack to setup possible associated types Thomas Schwinge

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).