https://gcc.gnu.org/g:65574f04d69a922eac21308f09d794fc8fab6a8c

commit 65574f04d69a922eac21308f09d794fc8fab6a8c
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Wed Mar 26 14:05:03 2025 +0000

    gccrs: fix unconstrained infer vars on generic associated type
    
    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.phi...@googlemail.com>

Diff:
---
 gcc/rust/typecheck/rust-hir-trait-reference.h  | 7 +++----
 gcc/rust/typecheck/rust-hir-trait-resolve.cc   | 8 ++++----
 gcc/rust/typecheck/rust-hir-type-check-path.cc | 4 ++--
 gcc/testsuite/rust/compile/issue-3242.rs       | 1 -
 4 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-trait-reference.h 
b/gcc/rust/typecheck/rust-hir-trait-reference.h
index 307dca471607..5866a2334cd5 100644
--- a/gcc/rust/typecheck/rust-hir-trait-reference.h
+++ b/gcc/rust/typecheck/rust-hir-trait-reference.h
@@ -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 ();
 
diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc 
b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
index 71ae7dfe6ab4..811abcbaeea4 100644
--- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc
+++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc
@@ -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;
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc 
b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 1904eba0c194..74ab1414e584 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -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);
            }
        }
 
diff --git a/gcc/testsuite/rust/compile/issue-3242.rs 
b/gcc/testsuite/rust/compile/issue-3242.rs
index 468497a4792e..a4542aea00b0 100644
--- a/gcc/testsuite/rust/compile/issue-3242.rs
+++ b/gcc/testsuite/rust/compile/issue-3242.rs
@@ -1,5 +1,4 @@
 #[lang = "sized"]
-// { dg-skip-if "" { *-*-* } }
 pub trait Sized {}
 
 trait Foo<T> {

Reply via email to