Point out region bound mismatches in check_region_bounds_on_impl_item
This commit is contained in:
@@ -1137,7 +1137,10 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||
// but found 0" it's confusing, because it looks like there
|
||||
// are zero. Since I don't quite know how to phrase things at
|
||||
// the moment, give a kind of vague error message.
|
||||
if trait_params != impl_params {
|
||||
if trait_params == impl_params {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let span = tcx
|
||||
.hir_get_generics(impl_m.def_id.expect_local())
|
||||
.expect("expected impl item to have generics or else we can't compare them")
|
||||
@@ -1146,6 +1149,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||
let mut generics_span = None;
|
||||
let mut bounds_span = vec![];
|
||||
let mut where_span = None;
|
||||
|
||||
if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
|
||||
&& let Some(trait_generics) = trait_node.generics()
|
||||
{
|
||||
@@ -1153,26 +1157,46 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||
// FIXME: we could potentially look at the impl's bounds to not point at bounds that
|
||||
// *are* present in the impl.
|
||||
for p in trait_generics.predicates {
|
||||
if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
|
||||
for b in pred.bounds {
|
||||
match p.kind {
|
||||
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
|
||||
bounds,
|
||||
..
|
||||
})
|
||||
| hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
|
||||
bounds,
|
||||
..
|
||||
}) => {
|
||||
for b in *bounds {
|
||||
if let hir::GenericBound::Outlives(lt) = b {
|
||||
bounds_span.push(lt.ident.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
|
||||
&& let Some(impl_generics) = impl_node.generics()
|
||||
{
|
||||
let mut impl_bounds = 0;
|
||||
for p in impl_generics.predicates {
|
||||
if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
|
||||
for b in pred.bounds {
|
||||
match p.kind {
|
||||
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
|
||||
bounds,
|
||||
..
|
||||
})
|
||||
| hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
|
||||
bounds,
|
||||
..
|
||||
}) => {
|
||||
for b in *bounds {
|
||||
if let hir::GenericBound::Outlives(_) = b {
|
||||
impl_bounds += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if impl_bounds == bounds_span.len() {
|
||||
bounds_span = vec![];
|
||||
@@ -1181,6 +1205,7 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let reported = tcx
|
||||
.dcx()
|
||||
.create_err(LifetimesOrBoundsMismatchOnTrait {
|
||||
@@ -1192,10 +1217,8 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||
where_span,
|
||||
})
|
||||
.emit_unless(delay);
|
||||
return Err(reported);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Err(reported)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(infcx))]
|
||||
|
||||
@@ -11,7 +11,10 @@ error[E0195]: lifetime parameters or bounds on method `has_bound` do not match t
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:23:17
|
||||
|
|
||||
LL | fn has_bound<'b:'a>(self, b: Inv<'b>);
|
||||
| ------- lifetimes in impl do not match this method in trait
|
||||
| -------
|
||||
| | |
|
||||
| | this bound might be missing in the impl
|
||||
| lifetimes in impl do not match this method in trait
|
||||
...
|
||||
LL | fn has_bound<'b>(self, b: Inv<'b>) {
|
||||
| ^^^^ lifetimes do not match method in trait
|
||||
@@ -58,7 +61,11 @@ error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not matc
|
||||
--> $DIR/regions-bound-missing-bound-in-impl.rs:42:20
|
||||
|
|
||||
LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
|
||||
| ---------------- lifetimes in impl do not match this method in trait
|
||||
| ----------------
|
||||
| | | |
|
||||
| | | this bound might be missing in the impl
|
||||
| | this bound might be missing in the impl
|
||||
| lifetimes in impl do not match this method in trait
|
||||
...
|
||||
LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
|
||||
| ^ lifetimes do not match method in trait
|
||||
|
||||
@@ -8,6 +8,7 @@ struct Foo;
|
||||
impl Trait for Foo {
|
||||
fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
|
||||
//~^ NOTE lifetimes do not match associated function in trait
|
||||
//~| NOTE this bound might be missing in the impl
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@ error[E0195]: lifetime parameters or bounds on associated function `bar` do not
|
||||
--> $DIR/E0195.rs:9:11
|
||||
|
|
||||
LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
|
||||
| ---------- lifetimes in impl do not match this associated function in trait
|
||||
| ----------
|
||||
| | |
|
||||
| | this bound might be missing in the impl
|
||||
| lifetimes in impl do not match this associated function in trait
|
||||
...
|
||||
LL | fn bar<'a,'b>(x: &'a str, y: &'b str) {
|
||||
| ^^^^^^^ lifetimes do not match associated function in trait
|
||||
|
||||
Reference in New Issue
Block a user