Skip to content

Commit b27d630

Browse files
Point out region bound mismatches in check_region_bounds_on_impl_item
1 parent 3ef8e64 commit b27d630

File tree

4 files changed

+80
-46
lines changed

4 files changed

+80
-46
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+66-43
Original file line numberDiff line numberDiff line change
@@ -1137,65 +1137,88 @@ fn check_region_bounds_on_impl_item<'tcx>(
11371137
// but found 0" it's confusing, because it looks like there
11381138
// are zero. Since I don't quite know how to phrase things at
11391139
// the moment, give a kind of vague error message.
1140-
if trait_params != impl_params {
1141-
let span = tcx
1142-
.hir_get_generics(impl_m.def_id.expect_local())
1143-
.expect("expected impl item to have generics or else we can't compare them")
1144-
.span;
1145-
1146-
let mut generics_span = None;
1147-
let mut bounds_span = vec![];
1148-
let mut where_span = None;
1149-
if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
1150-
&& let Some(trait_generics) = trait_node.generics()
1151-
{
1152-
generics_span = Some(trait_generics.span);
1153-
// FIXME: we could potentially look at the impl's bounds to not point at bounds that
1154-
// *are* present in the impl.
1155-
for p in trait_generics.predicates {
1156-
if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
1157-
for b in pred.bounds {
1140+
if trait_params == impl_params {
1141+
return Ok(());
1142+
}
1143+
1144+
let span = tcx
1145+
.hir_get_generics(impl_m.def_id.expect_local())
1146+
.expect("expected impl item to have generics or else we can't compare them")
1147+
.span;
1148+
1149+
let mut generics_span = None;
1150+
let mut bounds_span = vec![];
1151+
let mut where_span = None;
1152+
1153+
if let Some(trait_node) = tcx.hir_get_if_local(trait_m.def_id)
1154+
&& let Some(trait_generics) = trait_node.generics()
1155+
{
1156+
generics_span = Some(trait_generics.span);
1157+
// FIXME: we could potentially look at the impl's bounds to not point at bounds that
1158+
// *are* present in the impl.
1159+
for p in trait_generics.predicates {
1160+
match p.kind {
1161+
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1162+
bounds,
1163+
..
1164+
})
1165+
| hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1166+
bounds,
1167+
..
1168+
}) => {
1169+
for b in *bounds {
11581170
if let hir::GenericBound::Outlives(lt) = b {
11591171
bounds_span.push(lt.ident.span);
11601172
}
11611173
}
11621174
}
1175+
_ => {}
11631176
}
1164-
if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
1165-
&& let Some(impl_generics) = impl_node.generics()
1166-
{
1167-
let mut impl_bounds = 0;
1168-
for p in impl_generics.predicates {
1169-
if let hir::WherePredicateKind::BoundPredicate(pred) = p.kind {
1170-
for b in pred.bounds {
1177+
}
1178+
if let Some(impl_node) = tcx.hir_get_if_local(impl_m.def_id)
1179+
&& let Some(impl_generics) = impl_node.generics()
1180+
{
1181+
let mut impl_bounds = 0;
1182+
for p in impl_generics.predicates {
1183+
match p.kind {
1184+
hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
1185+
bounds,
1186+
..
1187+
})
1188+
| hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
1189+
bounds,
1190+
..
1191+
}) => {
1192+
for b in *bounds {
11711193
if let hir::GenericBound::Outlives(_) = b {
11721194
impl_bounds += 1;
11731195
}
11741196
}
11751197
}
1176-
}
1177-
if impl_bounds == bounds_span.len() {
1178-
bounds_span = vec![];
1179-
} else if impl_generics.has_where_clause_predicates {
1180-
where_span = Some(impl_generics.where_clause_span);
1198+
_ => {}
11811199
}
11821200
}
1201+
if impl_bounds == bounds_span.len() {
1202+
bounds_span = vec![];
1203+
} else if impl_generics.has_where_clause_predicates {
1204+
where_span = Some(impl_generics.where_clause_span);
1205+
}
11831206
}
1184-
let reported = tcx
1185-
.dcx()
1186-
.create_err(LifetimesOrBoundsMismatchOnTrait {
1187-
span,
1188-
item_kind: impl_m.descr(),
1189-
ident: impl_m.ident(tcx),
1190-
generics_span,
1191-
bounds_span,
1192-
where_span,
1193-
})
1194-
.emit_unless(delay);
1195-
return Err(reported);
11961207
}
11971208

1198-
Ok(())
1209+
let reported = tcx
1210+
.dcx()
1211+
.create_err(LifetimesOrBoundsMismatchOnTrait {
1212+
span,
1213+
item_kind: impl_m.descr(),
1214+
ident: impl_m.ident(tcx),
1215+
generics_span,
1216+
bounds_span,
1217+
where_span,
1218+
})
1219+
.emit_unless(delay);
1220+
1221+
Err(reported)
11991222
}
12001223

12011224
#[instrument(level = "debug", skip(infcx))]

tests/ui/borrowck/regions-bound-missing-bound-in-impl.stderr

+9-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ error[E0195]: lifetime parameters or bounds on method `has_bound` do not match t
1111
--> $DIR/regions-bound-missing-bound-in-impl.rs:23:17
1212
|
1313
LL | fn has_bound<'b:'a>(self, b: Inv<'b>);
14-
| ------- lifetimes in impl do not match this method in trait
14+
| -------
15+
| | |
16+
| | this bound might be missing in the impl
17+
| lifetimes in impl do not match this method in trait
1518
...
1619
LL | fn has_bound<'b>(self, b: Inv<'b>) {
1720
| ^^^^ lifetimes do not match method in trait
@@ -58,7 +61,11 @@ error[E0195]: lifetime parameters or bounds on method `wrong_bound2` do not matc
5861
--> $DIR/regions-bound-missing-bound-in-impl.rs:42:20
5962
|
6063
LL | fn wrong_bound2<'b,'c,'d:'a+'b>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>);
61-
| ---------------- lifetimes in impl do not match this method in trait
64+
| ----------------
65+
| | | |
66+
| | | this bound might be missing in the impl
67+
| | this bound might be missing in the impl
68+
| lifetimes in impl do not match this method in trait
6269
...
6370
LL | fn wrong_bound2(self, b: Inv, c: Inv, d: Inv) {
6471
| ^ lifetimes do not match method in trait

tests/ui/error-codes/E0195.rs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct Foo;
88
impl Trait for Foo {
99
fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
1010
//~^ NOTE lifetimes do not match associated function in trait
11+
//~| NOTE this bound might be missing in the impl
1112
}
1213
}
1314

tests/ui/error-codes/E0195.stderr

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ error[E0195]: lifetime parameters or bounds on associated function `bar` do not
22
--> $DIR/E0195.rs:9:11
33
|
44
LL | fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
5-
| ---------- lifetimes in impl do not match this associated function in trait
5+
| ----------
6+
| | |
7+
| | this bound might be missing in the impl
8+
| lifetimes in impl do not match this associated function in trait
69
...
710
LL | fn bar<'a,'b>(x: &'a str, y: &'b str) {
811
| ^^^^^^^ lifetimes do not match associated function in trait

0 commit comments

Comments
 (0)