]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Add check bounds flag to unify rules for compatability checks
authorPhilip Herron <herron.philip@googlemail.com>
Fri, 29 Aug 2025 15:36:45 +0000 (16:36 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 19:58:56 +0000 (20:58 +0100)
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 <herron.philip@googlemail.com>
gcc/rust/typecheck/rust-type-util.cc
gcc/rust/typecheck/rust-type-util.h
gcc/rust/typecheck/rust-tyty-bounds.cc
gcc/rust/typecheck/rust-unify.cc
gcc/rust/typecheck/rust-unify.h

index 83fffb3b47c2ca74323678356b99085172a8638d..34e99d34bb32dc72ff2ae5d858e0476d357476ab 100644 (file)
@@ -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,
index cd09b3fb73a788af2c9411222f1b377efbba77aa..7f4a94e2ae1bcd5b232ed06dabc536a50b1c796f 100644 (file)
@@ -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,
index c3682c6b17537d61868a5d455f9778c320c624f4..a59de993b0b77e4581c2fa73ccd3764e727d1990 100644 (file)
@@ -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;
index 5c1e5b732cdd16ba4ba18a2c94d93986880fa910..3a99b2a4f09528f03365d77444639f69602e0d41 100644 (file)
@@ -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);
+               }
            }
        }
     }
index fc7e8666ab06628962ba22c4c58a463eac88dbc2..91b2b7a70905150b9f001b16e00a7661137ef8cf 100644 (file)
@@ -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;