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;
