]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: fix unconstrained infer vars on generic associated type
authorPhilip Herron <herron.philip@googlemail.com>
Wed, 26 Mar 2025 14:05:03 +0000 (14:05 +0000)
committerArthur Cohen <arthur.cohen@embecosm.com>
Mon, 31 Mar 2025 19:07:16 +0000 (21:07 +0200)
The trick here is that when Bar::test is resolved it resolves to the
trait method:

  fn <Bar<i32>, T> (placeholder) -> placeholder

Which is fine so we need to setup the associated types for Bar<i32> which
means looking up the associated impl block then setting up the projection
of A = T so it becomes:

  fn <Bar<i32>, T> (placeholder: projection<T>:T)
    -> placeholder: projection<T>:T

But previously it was auto injecting inference variables so it became:

  fn <Bar<i32>, T> (placeholder: projection<T>:?T)
    -> placeholder: projection<T>:?T

The issue is that the binding of the generics was still T so this caused
inference variables to be injected again but unlinked. A possible tweak
would be that we are substituting again with new infer vars to actually
just unify them enplace so they are all part of the chain. This still
might be needed but lets hold off for now.

So basically when we are Path probing we dont allow GAT's to generate new
inference vars because they wont be bound to this current segment which
just causes confusion.

Fixes Rust-GCC#3242

gcc/rust/ChangeLog:

* typecheck/rust-hir-trait-reference.h: add default infer arg
* typecheck/rust-hir-trait-resolve.cc: dont add new infer vars
* typecheck/rust-hir-type-check-path.cc (TypeCheckExpr::resolve_segments): dont infer

gcc/testsuite/ChangeLog:

* rust/compile/issue-3242.rs: no longer skip the test

Signed-off-by: Philip Herron <herron.philip@googlemail.com>
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/testsuite/rust/compile/issue-3242.rs

index 6a570ed0fdbea799c220f0ccb28e53fef9253830..8b1ac7daf7f1c91a24ae87fb2f7473e3a4c79b31 100644 (file)
@@ -254,10 +254,9 @@ public:
 
   void setup_raw_associated_types ();
 
-  TyTy::BaseType *
-  setup_associated_types (const TyTy::BaseType *self,
-                         const TyTy::TypeBoundPredicate &bound,
-                         TyTy::SubstitutionArgumentMappings *args = nullptr);
+  TyTy::BaseType *setup_associated_types (
+    const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound,
+    TyTy::SubstitutionArgumentMappings *args = nullptr, bool infer = true);
 
   void reset_associated_types ();
 
index c07425d48b7a8b3495f50ec52960d6b2eff519f0..e4a61bdb0629ff7220c45430db4e32479ddb5856 100644 (file)
@@ -485,7 +485,7 @@ AssociatedImplTrait::setup_raw_associated_types ()
 TyTy::BaseType *
 AssociatedImplTrait::setup_associated_types (
   const TyTy::BaseType *self, const TyTy::TypeBoundPredicate &bound,
-  TyTy::SubstitutionArgumentMappings *args)
+  TyTy::SubstitutionArgumentMappings *args, bool infer)
 {
   // compute the constrained impl block generic arguments based on self and the
   // higher ranked trait bound
@@ -545,7 +545,7 @@ AssociatedImplTrait::setup_associated_types (
   std::vector<TyTy::SubstitutionArg> subst_args;
   for (auto &p : substitutions)
     {
-      if (p.needs_substitution ())
+      if (p.needs_substitution () && infer)
        {
          TyTy::TyVar infer_var = TyTy::TyVar::get_implicit_infer_var (locus);
          subst_args.push_back (
@@ -619,7 +619,7 @@ AssociatedImplTrait::setup_associated_types (
        = unify_site_and (a->get_ref (), TyTy::TyWithLocation (a),
                          TyTy::TyWithLocation (b), impl_predicate.get_locus (),
                          true /*emit-errors*/, true /*commit-if-ok*/,
-                         false /*infer*/, true /*cleanup-on-fail*/);
+                         true /*infer*/, true /*cleanup-on-fail*/);
       rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
     }
 
@@ -632,7 +632,7 @@ AssociatedImplTrait::setup_associated_types (
                                TyTy::TyWithLocation (impl_self_infer),
                                impl_predicate.get_locus (),
                                true /*emit-errors*/, true /*commit-if-ok*/,
-                               false /*infer*/, true /*cleanup-on-fail*/);
+                               true /*infer*/, true /*cleanup-on-fail*/);
   rust_assert (result->get_kind () != TyTy::TypeKind::ERROR);
   TyTy::BaseType *self_result = result;
 
index 33570ffa1c73aa9fa13675644ac5e368e94cc0f2..1fe39aaeb649ebe7d0e07f21ed431d37f922f272 100644 (file)
@@ -535,8 +535,8 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
                = impl_block_ty->lookup_predicate (trait_ref.get_defid ());
              if (!predicate.is_error ())
                impl_block_ty
-                 = associated->setup_associated_types (prev_segment,
-                                                       predicate);
+                 = associated->setup_associated_types (prev_segment, predicate,
+                                                       nullptr, false);
            }
        }
 
index 468497a4792ef56e5ad64292fccbf63a5b5de16e..a4542aea00b080fef10c3615879529067850d2ad 100644 (file)
@@ -1,5 +1,4 @@
 #[lang = "sized"]
-// { dg-skip-if "" { *-*-* } }
 pub trait Sized {}
 
 trait Foo<T> {