https://gcc.gnu.org/g:1a42fc3b3a604bf058b1f064cdf2b54389ee5b06

commit r16-4832-g1a42fc3b3a604bf058b1f064cdf2b54389ee5b06
Author: Philip Herron <[email protected]>
Date:   Fri Aug 29 16:36:45 2025 +0100

    gccrs: Add check bounds flag to unify rules for compatability checks
    
    We need to make the type bounds check a flag because it can turn into a
    recursive type bounds check. This allows us to remove another can_eq usage
    
    gcc/rust/ChangeLog:
    
            * typecheck/rust-type-util.cc (types_compatable):  add check bounds 
flag
            (unify_site_and): likewise
            * typecheck/rust-type-util.h (types_compatable): likewise
            (unify_site_and): likewise
            * typecheck/rust-tyty-bounds.cc: likewise
            * typecheck/rust-unify.cc (UnifyRules::UnifyRules): likewise
            (UnifyRules::Resolve): likewise
            (UnifyRules::resolve_subtype): likewise
            (UnifyRules::go): likewise
            * typecheck/rust-unify.h: likewise
    
    Signed-off-by: Philip Herron <[email protected]>

Diff:
---
 gcc/rust/typecheck/rust-type-util.cc   | 27 ++++++++-------
 gcc/rust/typecheck/rust-type-util.h    |  5 +--
 gcc/rust/typecheck/rust-tyty-bounds.cc |  9 +++--
 gcc/rust/typecheck/rust-unify.cc       | 60 +++++++++++++++++++---------------
 gcc/rust/typecheck/rust-unify.h        |  4 ++-
 5 files changed, 58 insertions(+), 47 deletions(-)

diff --git a/gcc/rust/typecheck/rust-type-util.cc 
b/gcc/rust/typecheck/rust-type-util.cc
index 83fffb3b47c2..34e99d34bb32 100644
--- a/gcc/rust/typecheck/rust-type-util.cc
+++ b/gcc/rust/typecheck/rust-type-util.cc
@@ -152,11 +152,12 @@ query_type (HirId reference, TyTy::BaseType **result)
 
 bool
 types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
-                 location_t unify_locus, bool emit_errors)
+                 location_t unify_locus, bool emit_errors, bool check_bounds)
 {
   TyTy::BaseType *result
     = unify_site_and (UNKNOWN_HIRID, lhs, rhs, unify_locus, emit_errors,
-                     false /*commit*/, true /*infer*/, true /*cleanup*/);
+                     false /*commit*/, true /*infer*/, true /*cleanup*/,
+                     check_bounds);
   return result->get_kind () != TyTy::TypeKind::ERROR;
 }
 
@@ -173,32 +174,34 @@ unify_site (HirId id, TyTy::TyWithLocation lhs, 
TyTy::TyWithLocation rhs,
   std::vector<UnifyRules::CommitSite> commits;
   std::vector<UnifyRules::InferenceSite> infers;
   return UnifyRules::Resolve (lhs, rhs, unify_locus, true /*commit*/,
-                             true /*emit_error*/, false /*infer*/, commits,
-                             infers);
+                             true /*emit_error*/, false /*infer*/,
+                             true /*check_bounds*/, commits, infers);
 }
 
 TyTy::BaseType *
 unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
                location_t unify_locus, bool emit_errors, bool commit_if_ok,
-               bool implicit_infer_vars, bool cleanup)
+               bool implicit_infer_vars, bool cleanup, bool check_bounds)
 {
   TypeCheckContext &context = *TypeCheckContext::get ();
 
   TyTy::BaseType *expected = lhs.get_ty ();
   TyTy::BaseType *expr = rhs.get_ty ();
 
-  rust_debug_loc (
-    unify_locus,
-    "begin unify_site_and commit %s infer %s id={%u} expected={%s} expr={%s}",
-    commit_if_ok ? "true" : "false", implicit_infer_vars ? "true" : "false",
-    id == UNKNOWN_HIRID ? 0 : id, expected->debug_str ().c_str (),
-    expr->debug_str ().c_str ());
+  rust_debug_loc (unify_locus,
+                 "begin unify_site_and commit %s infer %s check_bounds %s "
+                 "id={%u} expected={%s} expr={%s}",
+                 commit_if_ok ? "true" : "false",
+                 implicit_infer_vars ? "true" : "false",
+                 check_bounds ? "true" : "false", id == UNKNOWN_HIRID ? 0 : id,
+                 expected->debug_str ().c_str (), expr->debug_str ().c_str ());
 
   std::vector<UnifyRules::CommitSite> commits;
   std::vector<UnifyRules::InferenceSite> infers;
   TyTy::BaseType *result
     = UnifyRules::Resolve (lhs, rhs, unify_locus, false /*commit inline*/,
-                          emit_errors, implicit_infer_vars, commits, infers);
+                          emit_errors, implicit_infer_vars, check_bounds,
+                          commits, infers);
   bool ok = result->get_kind () != TyTy::TypeKind::ERROR;
 
   rust_debug_loc (unify_locus,
diff --git a/gcc/rust/typecheck/rust-type-util.h 
b/gcc/rust/typecheck/rust-type-util.h
index cd09b3fb73a7..7f4a94e2ae1b 100644
--- a/gcc/rust/typecheck/rust-type-util.h
+++ b/gcc/rust/typecheck/rust-type-util.h
@@ -28,7 +28,8 @@ namespace Resolver {
 bool query_type (HirId reference, TyTy::BaseType **result);
 
 bool types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
-                      location_t unify_locus, bool emit_errors);
+                      location_t unify_locus, bool emit_errors,
+                      bool check_bounds = true);
 
 TyTy::BaseType *unify_site (HirId id, TyTy::TyWithLocation lhs,
                            TyTy::TyWithLocation rhs, location_t unify_locus);
@@ -37,7 +38,7 @@ TyTy::BaseType *unify_site_and (HirId id, 
TyTy::TyWithLocation lhs,
                                TyTy::TyWithLocation rhs,
                                location_t unify_locus, bool emit_errors,
                                bool commit_if_ok, bool implicit_infer_vars,
-                               bool cleanup);
+                               bool cleanup, bool check_bounds = true);
 
 TyTy::BaseType *coercion_site (HirId id, TyTy::TyWithLocation lhs,
                               TyTy::TyWithLocation rhs,
diff --git a/gcc/rust/typecheck/rust-tyty-bounds.cc 
b/gcc/rust/typecheck/rust-tyty-bounds.cc
index c3682c6b1753..a59de993b0b7 100644
--- a/gcc/rust/typecheck/rust-tyty-bounds.cc
+++ b/gcc/rust/typecheck/rust-tyty-bounds.cc
@@ -81,11 +81,10 @@ TypeBoundsProbe::process_impl_block (
   if (!query_type (impl_ty_id, &impl_type))
     return true;
 
-  if (!receiver->can_eq (impl_type, false))
-    {
-      if (!impl_type->can_eq (receiver, false))
-       return true;
-    }
+  if (!types_compatable (TyTy::TyWithLocation (receiver),
+                        TyTy::TyWithLocation (impl_type), impl->get_locus (),
+                        false /*emit_errors*/, false /*check-bounds*/))
+    return true;
 
   possible_trait_paths.emplace_back (&impl->get_trait_ref (), impl);
   return true;
diff --git a/gcc/rust/typecheck/rust-unify.cc b/gcc/rust/typecheck/rust-unify.cc
index 5c1e5b732cdd..3a99b2a4f095 100644
--- a/gcc/rust/typecheck/rust-unify.cc
+++ b/gcc/rust/typecheck/rust-unify.cc
@@ -26,22 +26,24 @@ namespace Resolver {
 
 UnifyRules::UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
                        location_t locus, bool commit_flag, bool emit_error,
-                       bool infer, std::vector<CommitSite> &commits,
+                       bool check_bounds, bool infer,
+                       std::vector<CommitSite> &commits,
                        std::vector<InferenceSite> &infers)
   : lhs (lhs), rhs (rhs), locus (locus), commit_flag (commit_flag),
-    emit_error (emit_error), infer_flag (infer), commits (commits),
-    infers (infers), mappings (Analysis::Mappings::get ()),
-    context (*TypeCheckContext::get ())
+    emit_error (emit_error), infer_flag (infer),
+    check_bounds_flag (check_bounds), commits (commits), infers (infers),
+    mappings (Analysis::Mappings::get ()), context (*TypeCheckContext::get ())
 {}
 
 TyTy::BaseType *
 UnifyRules::Resolve (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
                     location_t locus, bool commit_flag, bool emit_error,
-                    bool infer, std::vector<CommitSite> &commits,
+                    bool check_bounds, bool infer,
+                    std::vector<CommitSite> &commits,
                     std::vector<InferenceSite> &infers)
 {
-  UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, commits,
-               infers);
+  UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, check_bounds,
+               commits, infers);
 
   TyTy::BaseType *result = r.go ();
   commits.emplace_back (lhs.get_ty (), rhs.get_ty (), result);
@@ -60,7 +62,7 @@ UnifyRules::resolve_subtype (TyTy::TyWithLocation lhs, 
TyTy::TyWithLocation rhs)
 {
   TyTy::BaseType *result
     = UnifyRules::Resolve (lhs, rhs, locus, commit_flag, emit_error, 
infer_flag,
-                          commits, infers);
+                          check_bounds_flag, commits, infers);
 
   // If the recursive call resulted in an error and would have emitted an error
   // message, disable error emission for the current level to avoid duplicate
@@ -161,30 +163,34 @@ UnifyRules::go ()
   rust_debug ("unify::go ltype={%s} rtype={%s}", ltype->debug_str ().c_str (),
              rtype->debug_str ().c_str ());
 
-  // check bounds
-  bool ltype_is_placeholder = ltype->get_kind () == 
TyTy::TypeKind::PLACEHOLDER;
-  bool rtype_is_placeholder = rtype->get_kind () == 
TyTy::TypeKind::PLACEHOLDER;
-  bool types_equal = ltype->is_equal (*rtype);
-  bool should_check_bounds
-    = !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
-  if (should_check_bounds)
+  if (check_bounds_flag)
     {
-      if (ltype->num_specified_bounds () > 0)
+      bool ltype_is_placeholder
+       = ltype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
+      bool rtype_is_placeholder
+       = rtype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
+      bool types_equal = ltype->is_equal (*rtype);
+      bool should_check_bounds
+       = !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
+      if (should_check_bounds)
        {
-         if (!ltype->bounds_compatible (*rtype, locus, emit_error))
+         if (ltype->num_specified_bounds () > 0)
            {
-             // already emitted an error
-             emit_error = false;
-             return new TyTy::ErrorType (0);
+             if (!ltype->bounds_compatible (*rtype, locus, emit_error))
+               {
+                 // already emitted an error
+                 emit_error = false;
+                 return new TyTy::ErrorType (0);
+               }
            }
-       }
-      else if (rtype->num_specified_bounds () > 0)
-       {
-         if (!rtype->bounds_compatible (*ltype, locus, emit_error))
+         else if (rtype->num_specified_bounds () > 0)
            {
-             // already emitted an error
-             emit_error = false;
-             return new TyTy::ErrorType (0);
+             if (!rtype->bounds_compatible (*ltype, locus, emit_error))
+               {
+                 // already emitted an error
+                 emit_error = false;
+                 return new TyTy::ErrorType (0);
+               }
            }
        }
     }
diff --git a/gcc/rust/typecheck/rust-unify.h b/gcc/rust/typecheck/rust-unify.h
index fc7e8666ab06..91b2b7a70905 100644
--- a/gcc/rust/typecheck/rust-unify.h
+++ b/gcc/rust/typecheck/rust-unify.h
@@ -55,6 +55,7 @@ public:
   static TyTy::BaseType *Resolve (TyTy::TyWithLocation lhs,
                                  TyTy::TyWithLocation rhs, location_t locus,
                                  bool commit_flag, bool emit_error, bool infer,
+                                 bool check_bounds,
                                  std::vector<CommitSite> &commits,
                                  std::vector<InferenceSite> &infers);
 
@@ -99,7 +100,7 @@ protected:
 private:
   UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
              location_t locus, bool commit_flag, bool emit_error, bool infer,
-             std::vector<CommitSite> &commits,
+             bool check_bounds, std::vector<CommitSite> &commits,
              std::vector<InferenceSite> &infers);
 
   TyTy::BaseType *resolve_subtype (TyTy::TyWithLocation lhs,
@@ -120,6 +121,7 @@ private:
   bool commit_flag;
   bool emit_error;
   bool infer_flag;
+  bool check_bounds_flag;
   std::vector<CommitSite> &commits;
   std::vector<InferenceSite> &infers;

Reply via email to