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;
}
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,
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);
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,
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;
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);
{
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
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);
+ }
}
}
}
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);
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,
bool commit_flag;
bool emit_error;
bool infer_flag;
+ bool check_bounds_flag;
std::vector<CommitSite> &commits;
std::vector<InferenceSite> &infers;