]> 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)
committerPhilip Herron <herron.philip@googlemail.com>
Sun, 5 Feb 2023 00:10:48 +0000 (00:10 +0000)
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 d0814f60eafdf55b8bfe29df3efea7f08b47564d..0d4da3b59cf3932fb1bc0b692843dca678d93436 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 b293279a82496f5ddd1c61b9e97f5dfac08223b7..a7e073551f0c8b0c45bcaa3fc1fde77059b59828 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 4e765ad1380ae48af1e9b3c5a7c9701944e5c60d..1625eda373b69f10b9913974dc62d3fbbca54a7e 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 6334b69c87d6160a1f1794f32ab72d7d7809e44c..6ff0113e66b55aba3bbf091ed40d031ea3915eaa 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);
+}