// FIXME this is missing locus
bool
-BaseType::satisfies_bound (const TypeBoundPredicate &predicate) const
+BaseType::satisfies_bound (const TypeBoundPredicate &predicate,
+ bool emit_error) const
{
+ bool is_infer_var = destructure ()->get_kind () == TyTy::TypeKind::INFER;
+
const Resolver::TraitReference *query = predicate.get ();
for (const auto &bound : specified_bounds)
{
return true;
}
+ if (is_infer_var)
+ return true;
+
bool satisfied = false;
auto probed = Resolver::TypeBoundsProbe::Probe (this);
for (const auto &b : probed)
const HIR::ImplBlock &impl = *(b.second);
for (const auto &item : impl.get_impl_items ())
{
+ bool is_associated_type = item->get_impl_item_type ()
+ == HIR::ImplItem::ImplItemType::TYPE_ALIAS;
+ if (!is_associated_type)
+ continue;
+
TyTy::BaseType *impl_item_ty = nullptr;
Analysis::NodeMapping i = item->get_impl_mappings ();
bool query_ok = Resolver::query_type (i.get_hirid (), &impl_item_ty);
// compare the types
if (!bound_ty->can_eq (impl_item_ty, false))
{
- RichLocation r (mappings->lookup_location (get_ref ()));
- r.add_range (predicate.get_locus ());
- r.add_range (mappings->lookup_location (i.get_hirid ()));
-
- rust_error_at (
- r, "expected %<%s%> got %<%s%>",
- bound_ty->destructure ()->get_name ().c_str (),
- impl_item_ty->destructure ()->get_name ().c_str ());
- return false;
+ if (!impl_item_ty->can_eq (bound_ty, false))
+ {
+ if (emit_error)
+ {
+ RichLocation r (mappings->lookup_location (get_ref ()));
+ r.add_range (predicate.get_locus ());
+ r.add_range (mappings->lookup_location (i.get_hirid ()));
+
+ rust_error_at (
+ r, "expected %<%s%> got %<%s%>",
+ bound_ty->destructure ()->get_name ().c_str (),
+ impl_item_ty->destructure ()->get_name ().c_str ());
+ }
+ return false;
+ }
}
}
unsatisfied_bounds;
for (auto &bound : get_specified_bounds ())
{
- if (!other.satisfies_bound (bound))
+ if (!other.satisfies_bound (bound, emit_error))
unsatisfied_bounds.push_back (bound);
}
// 2. (For functions) have the same signature
virtual bool is_equal (const BaseType &other) const;
- bool satisfies_bound (const TypeBoundPredicate &predicate) const;
+ bool satisfies_bound (const TypeBoundPredicate &predicate,
+ bool emit_error) const;
bool bounds_compatible (const BaseType &other, Location locus,
bool emit_error) const;
void inherit_bounds (const BaseType &other);
rtype->debug_str ().c_str ());
// check bounds
- if (ltype->num_specified_bounds () > 0)
+ bool should_check_bounds = !ltype->is_equal (*rtype);
+ 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))
+ {
+ // already emitted an error
+ emit_error = false;
+ return new TyTy::ErrorType (0);
+ }
}
}