Skip to content

Commit fd14a31

Browse files
committed
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]>
1 parent d05146f commit fd14a31

File tree

5 files changed

+58
-47
lines changed

5 files changed

+58
-47
lines changed

gcc/rust/typecheck/rust-type-util.cc

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,12 @@ query_type (HirId reference, TyTy::BaseType **result)
152152

153153
bool
154154
types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
155-
location_t unify_locus, bool emit_errors)
155+
location_t unify_locus, bool emit_errors, bool check_bounds)
156156
{
157157
TyTy::BaseType *result
158158
= unify_site_and (UNKNOWN_HIRID, lhs, rhs, unify_locus, emit_errors,
159-
false /*commit*/, true /*infer*/, true /*cleanup*/);
159+
false /*commit*/, true /*infer*/, true /*cleanup*/,
160+
check_bounds);
160161
return result->get_kind () != TyTy::TypeKind::ERROR;
161162
}
162163

@@ -173,32 +174,34 @@ unify_site (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
173174
std::vector<UnifyRules::CommitSite> commits;
174175
std::vector<UnifyRules::InferenceSite> infers;
175176
return UnifyRules::Resolve (lhs, rhs, unify_locus, true /*commit*/,
176-
true /*emit_error*/, false /*infer*/, commits,
177-
infers);
177+
true /*emit_error*/, false /*infer*/,
178+
true /*check_bounds*/, commits, infers);
178179
}
179180

180181
TyTy::BaseType *
181182
unify_site_and (HirId id, TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
182183
location_t unify_locus, bool emit_errors, bool commit_if_ok,
183-
bool implicit_infer_vars, bool cleanup)
184+
bool implicit_infer_vars, bool cleanup, bool check_bounds)
184185
{
185186
TypeCheckContext &context = *TypeCheckContext::get ();
186187

187188
TyTy::BaseType *expected = lhs.get_ty ();
188189
TyTy::BaseType *expr = rhs.get_ty ();
189190

190-
rust_debug_loc (
191-
unify_locus,
192-
"begin unify_site_and commit %s infer %s id={%u} expected={%s} expr={%s}",
193-
commit_if_ok ? "true" : "false", implicit_infer_vars ? "true" : "false",
194-
id == UNKNOWN_HIRID ? 0 : id, expected->debug_str ().c_str (),
195-
expr->debug_str ().c_str ());
191+
rust_debug_loc (unify_locus,
192+
"begin unify_site_and commit %s infer %s check_bounds %s "
193+
"id={%u} expected={%s} expr={%s}",
194+
commit_if_ok ? "true" : "false",
195+
implicit_infer_vars ? "true" : "false",
196+
check_bounds ? "true" : "false", id == UNKNOWN_HIRID ? 0 : id,
197+
expected->debug_str ().c_str (), expr->debug_str ().c_str ());
196198

197199
std::vector<UnifyRules::CommitSite> commits;
198200
std::vector<UnifyRules::InferenceSite> infers;
199201
TyTy::BaseType *result
200202
= UnifyRules::Resolve (lhs, rhs, unify_locus, false /*commit inline*/,
201-
emit_errors, implicit_infer_vars, commits, infers);
203+
emit_errors, implicit_infer_vars, check_bounds,
204+
commits, infers);
202205
bool ok = result->get_kind () != TyTy::TypeKind::ERROR;
203206

204207
rust_debug_loc (unify_locus,

gcc/rust/typecheck/rust-type-util.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ namespace Resolver {
2828
bool query_type (HirId reference, TyTy::BaseType **result);
2929

3030
bool types_compatable (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
31-
location_t unify_locus, bool emit_errors);
31+
location_t unify_locus, bool emit_errors,
32+
bool check_bounds = true);
3233

3334
TyTy::BaseType *unify_site (HirId id, TyTy::TyWithLocation lhs,
3435
TyTy::TyWithLocation rhs, location_t unify_locus);
@@ -37,7 +38,7 @@ TyTy::BaseType *unify_site_and (HirId id, TyTy::TyWithLocation lhs,
3738
TyTy::TyWithLocation rhs,
3839
location_t unify_locus, bool emit_errors,
3940
bool commit_if_ok, bool implicit_infer_vars,
40-
bool cleanup);
41+
bool cleanup, bool check_bounds = true);
4142

4243
TyTy::BaseType *coercion_site (HirId id, TyTy::TyWithLocation lhs,
4344
TyTy::TyWithLocation rhs,

gcc/rust/typecheck/rust-tyty-bounds.cc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,10 @@ TypeBoundsProbe::process_impl_block (
8181
if (!query_type (impl_ty_id, &impl_type))
8282
return true;
8383

84-
if (!receiver->can_eq (impl_type, false))
85-
{
86-
if (!impl_type->can_eq (receiver, false))
87-
return true;
88-
}
84+
if (!types_compatable (TyTy::TyWithLocation (receiver),
85+
TyTy::TyWithLocation (impl_type), impl->get_locus (),
86+
false /*emit_errors*/, false /*check-bounds*/))
87+
return true;
8988

9089
possible_trait_paths.emplace_back (&impl->get_trait_ref (), impl);
9190
return true;

gcc/rust/typecheck/rust-unify.cc

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,24 @@ namespace Resolver {
2626

2727
UnifyRules::UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
2828
location_t locus, bool commit_flag, bool emit_error,
29-
bool infer, std::vector<CommitSite> &commits,
29+
bool check_bounds, bool infer,
30+
std::vector<CommitSite> &commits,
3031
std::vector<InferenceSite> &infers)
3132
: lhs (lhs), rhs (rhs), locus (locus), commit_flag (commit_flag),
32-
emit_error (emit_error), infer_flag (infer), commits (commits),
33-
infers (infers), mappings (Analysis::Mappings::get ()),
34-
context (*TypeCheckContext::get ())
33+
emit_error (emit_error), infer_flag (infer),
34+
check_bounds_flag (check_bounds), commits (commits), infers (infers),
35+
mappings (Analysis::Mappings::get ()), context (*TypeCheckContext::get ())
3536
{}
3637

3738
TyTy::BaseType *
3839
UnifyRules::Resolve (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
3940
location_t locus, bool commit_flag, bool emit_error,
40-
bool infer, std::vector<CommitSite> &commits,
41+
bool check_bounds, bool infer,
42+
std::vector<CommitSite> &commits,
4143
std::vector<InferenceSite> &infers)
4244
{
43-
UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, commits,
44-
infers);
45+
UnifyRules r (lhs, rhs, locus, commit_flag, emit_error, infer, check_bounds,
46+
commits, infers);
4547

4648
TyTy::BaseType *result = r.go ();
4749
commits.emplace_back (lhs.get_ty (), rhs.get_ty (), result);
@@ -60,7 +62,7 @@ UnifyRules::resolve_subtype (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs)
6062
{
6163
TyTy::BaseType *result
6264
= UnifyRules::Resolve (lhs, rhs, locus, commit_flag, emit_error, infer_flag,
63-
commits, infers);
65+
check_bounds_flag, commits, infers);
6466

6567
// If the recursive call resulted in an error and would have emitted an error
6668
// message, disable error emission for the current level to avoid duplicate
@@ -161,30 +163,34 @@ UnifyRules::go ()
161163
rust_debug ("unify::go ltype={%s} rtype={%s}", ltype->debug_str ().c_str (),
162164
rtype->debug_str ().c_str ());
163165

164-
// check bounds
165-
bool ltype_is_placeholder = ltype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
166-
bool rtype_is_placeholder = rtype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
167-
bool types_equal = ltype->is_equal (*rtype);
168-
bool should_check_bounds
169-
= !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
170-
if (should_check_bounds)
166+
if (check_bounds_flag)
171167
{
172-
if (ltype->num_specified_bounds () > 0)
168+
bool ltype_is_placeholder
169+
= ltype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
170+
bool rtype_is_placeholder
171+
= rtype->get_kind () == TyTy::TypeKind::PLACEHOLDER;
172+
bool types_equal = ltype->is_equal (*rtype);
173+
bool should_check_bounds
174+
= !types_equal && !(ltype_is_placeholder || rtype_is_placeholder);
175+
if (should_check_bounds)
173176
{
174-
if (!ltype->bounds_compatible (*rtype, locus, emit_error))
177+
if (ltype->num_specified_bounds () > 0)
175178
{
176-
// already emitted an error
177-
emit_error = false;
178-
return new TyTy::ErrorType (0);
179+
if (!ltype->bounds_compatible (*rtype, locus, emit_error))
180+
{
181+
// already emitted an error
182+
emit_error = false;
183+
return new TyTy::ErrorType (0);
184+
}
179185
}
180-
}
181-
else if (rtype->num_specified_bounds () > 0)
182-
{
183-
if (!rtype->bounds_compatible (*ltype, locus, emit_error))
186+
else if (rtype->num_specified_bounds () > 0)
184187
{
185-
// already emitted an error
186-
emit_error = false;
187-
return new TyTy::ErrorType (0);
188+
if (!rtype->bounds_compatible (*ltype, locus, emit_error))
189+
{
190+
// already emitted an error
191+
emit_error = false;
192+
return new TyTy::ErrorType (0);
193+
}
188194
}
189195
}
190196
}

gcc/rust/typecheck/rust-unify.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class UnifyRules
5555
static TyTy::BaseType *Resolve (TyTy::TyWithLocation lhs,
5656
TyTy::TyWithLocation rhs, location_t locus,
5757
bool commit_flag, bool emit_error, bool infer,
58+
bool check_bounds,
5859
std::vector<CommitSite> &commits,
5960
std::vector<InferenceSite> &infers);
6061

@@ -99,7 +100,7 @@ class UnifyRules
99100
private:
100101
UnifyRules (TyTy::TyWithLocation lhs, TyTy::TyWithLocation rhs,
101102
location_t locus, bool commit_flag, bool emit_error, bool infer,
102-
std::vector<CommitSite> &commits,
103+
bool check_bounds, std::vector<CommitSite> &commits,
103104
std::vector<InferenceSite> &infers);
104105

105106
TyTy::BaseType *resolve_subtype (TyTy::TyWithLocation lhs,
@@ -120,6 +121,7 @@ class UnifyRules
120121
bool commit_flag;
121122
bool emit_error;
122123
bool infer_flag;
124+
bool check_bounds_flag;
123125
std::vector<CommitSite> &commits;
124126
std::vector<InferenceSite> &infers;
125127

0 commit comments

Comments
 (0)