]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Remove monomorphization hack to setup possible associated types
authorPhilip Herron <herron.philip@googlemail.com>
Fri, 27 Jan 2023 15:38:58 +0000 (15:38 +0000)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 6 Apr 2023 08:47:21 +0000 (10:47 +0200)
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.

gcc/rust/typecheck/rust-hir-trait-reference.h
gcc/rust/typecheck/rust-hir-trait-resolve.cc
gcc/rust/typecheck/rust-hir-type-check-path.cc
gcc/rust/typecheck/rust-tyty-call.cc
gcc/testsuite/rust/compile/issue-1773.rs [new file with mode: 0644]

index 0df35265959b65578a529b6798dd6bdf3d7cef78..9b4461b9f1880563fc483e7fa3bf4247228b9396 100644 (file)
@@ -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 ();
 
index e2d0cf2d7a2005b3eceae263d059bfda3a80ddd3..6e23093eceb1d45773e72765940147d6d292c733 100644 (file)
@@ -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
index 6f1fd416c19f78989bdc33ec8461ab925604ca00..9d9b2949944aff9a224299807ce9376dcb1afb27 100644 (file)
@@ -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),
index d520b595e43f382737d79ae247afbafcaa465965..4c6442e2d829f9e2662876ac714022e4f03b1bb0 100644 (file)
@@ -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 (file)
index 0000000..c627ac0
--- /dev/null
@@ -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);
+}