From: Philip Herron <[email protected]>
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]>
---
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 83fffb3b47c..34e99d34bb3 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 cd09b3fb73a..7f4a94e2ae1 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 c3682c6b175..a59de993b0b 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 5c1e5b732cd..3a99b2a4f09 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 fc7e8666ab0..91b2b7a7090 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;
--
2.50.1