Skip to content

Commit 5be0b22

Browse files
committed
improve the suggestion of generic_bound_failure
1 parent 6d27169 commit 5be0b22

28 files changed

+696
-384
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

Lines changed: 201 additions & 299 deletions
Large diffs are not rendered by default.

compiler/rustc_middle/src/ty/context.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,24 +1057,29 @@ impl<'tcx> TyCtxt<'tcx> {
10571057
}
10581058

10591059
/// Returns the `DefId` and the `BoundRegionKind` corresponding to the given region.
1060-
pub fn is_suitable_region(self, region: Region<'tcx>) -> Option<FreeRegionInfo> {
1061-
let (suitable_region_binding_scope, bound_region) = match *region {
1062-
ty::ReFree(ref free_region) => {
1063-
(free_region.scope.expect_local(), free_region.bound_region)
1060+
pub fn is_suitable_region(self, mut region: Region<'tcx>) -> Option<FreeRegionInfo> {
1061+
let (suitable_region_binding_scope, bound_region) = loop {
1062+
let def_id = match region.kind() {
1063+
ty::ReFree(fr) => fr.bound_region.get_id()?.as_local()?,
1064+
ty::ReEarlyBound(ebr) => ebr.def_id.expect_local(),
1065+
_ => return None, // not a free region
1066+
};
1067+
let scope = self.local_parent(def_id);
1068+
if self.def_kind(scope) == DefKind::OpaqueTy {
1069+
// Lifetime params of opaque types are synthetic and thus irrelevant to
1070+
// diagnostics. Map them back to their origin!
1071+
region = self.map_rpit_lifetime_to_fn_lifetime(def_id);
1072+
continue;
10641073
}
1065-
ty::ReEarlyBound(ref ebr) => (
1066-
self.local_parent(ebr.def_id.expect_local()),
1067-
ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name),
1068-
),
1069-
_ => return None, // not a free region
1074+
break (scope, ty::BrNamed(def_id.into(), self.item_name(def_id.into())));
10701075
};
10711076

10721077
let is_impl_item = match self.hir().find_by_def_id(suitable_region_binding_scope) {
10731078
Some(Node::Item(..) | Node::TraitItem(..)) => false,
10741079
Some(Node::ImplItem(..)) => {
10751080
self.is_bound_region_in_impl_item(suitable_region_binding_scope)
10761081
}
1077-
_ => return None,
1082+
_ => false,
10781083
};
10791084

10801085
Some(FreeRegionInfo {

tests/ui/associated-inherent-types/regionck-1.stderr

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ error[E0309]: the parameter type `T` may not live long enough
22
--> $DIR/regionck-1.rs:9:30
33
|
44
LL | type NoTyOutliv<'a, T> = &'a T;
5-
| ^^^^^- help: consider adding a where clause: `where T: 'a`
6-
| |
7-
| ...so that the reference type `&'a T` does not outlive the data it points at
5+
| ^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at
6+
|
7+
help: consider adding an explicit lifetime bound...
8+
|
9+
LL | type NoTyOutliv<'a, T: 'a> = &'a T;
10+
| ++++
811

912
error[E0491]: in type `&'a &'b ()`, reference has a longer lifetime than the data it references
1013
--> $DIR/regionck-1.rs:10:31

tests/ui/async-await/in-trait/async-generics-and-bounds.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ note: ...so that the reference type `&(T, U)` does not outlive the data it point
1414
|
1515
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
1616
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
help: consider adding an explicit lifetime bound...
18+
|
19+
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, U: 'a;
20+
| ++++ ++ ++ +++++++
1721

1822
error[E0311]: the parameter type `T` may not live long enough
1923
--> $DIR/async-generics-and-bounds.rs:12:5
@@ -31,6 +35,10 @@ note: ...so that the reference type `&(T, U)` does not outlive the data it point
3135
|
3236
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
3337
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38+
help: consider adding an explicit lifetime bound...
39+
|
40+
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Hash, T: 'a;
41+
| ++++ ++ ++ +++++++
3442

3543
error: aborting due to 2 previous errors
3644

tests/ui/async-await/in-trait/async-generics.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ note: ...so that the reference type `&(T, U)` does not outlive the data it point
1414
|
1515
LL | async fn foo(&self) -> &(T, U);
1616
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
help: consider adding an explicit lifetime bound...
18+
|
19+
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where U: 'a;
20+
| ++++ ++ ++ +++++++++++
1721

1822
error[E0311]: the parameter type `T` may not live long enough
1923
--> $DIR/async-generics.rs:9:5
@@ -31,6 +35,10 @@ note: ...so that the reference type `&(T, U)` does not outlive the data it point
3135
|
3236
LL | async fn foo(&self) -> &(T, U);
3337
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38+
help: consider adding an explicit lifetime bound...
39+
|
40+
LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: 'a;
41+
| ++++ ++ ++ +++++++++++
3442

3543
error: aborting due to 2 previous errors
3644

tests/ui/error-codes/E0311.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#![allow(warnings)]
44

5-
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
5+
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
66
with_restriction::<T>(x) //~ ERROR E0311
77
}
88

tests/ui/error-codes/E0311.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ LL | with_restriction::<T>(x)
1616
| ^^^^^^^^^^^^^^^^^^^^^
1717
help: consider adding an explicit lifetime bound...
1818
|
19-
LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
20-
| +++ ++++ ++
19+
LL | fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
20+
| +++ ++++ ++ ++
2121

2222
error: aborting due to previous error
2323

tests/ui/generic-associated-types/issue-84931.stderr

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ error[E0309]: the parameter type `T` may not live long enough
22
--> $DIR/issue-84931.rs:14:21
33
|
44
LL | type Item<'a> = &'a mut T;
5-
| ^^^^^^^^^- help: consider adding a where clause: `where T: 'a`
6-
| |
7-
| ...so that the reference type `&'a mut T` does not outlive the data it points at
5+
| ^^^^^^^^^ ...so that the reference type `&'a mut T` does not outlive the data it points at
6+
|
7+
help: consider adding an explicit lifetime bound...
8+
|
9+
LL | type Item<'a> = &'a mut T where T: 'a;
10+
| +++++++++++
811

912
error: aborting due to previous error
1013

tests/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
1717
|
1818
help: consider adding an explicit lifetime bound...
1919
|
20-
LL | impl<K: 'a> Nested<K> {
21-
| ++++
20+
LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() where K: 'a {
21+
| +++++++++++
2222

2323
error[E0309]: the parameter type `M` may not live long enough
2424
--> $DIR/lifetime-doesnt-live-long-enough.rs:44:36
@@ -39,17 +39,19 @@ LL | fn foo<'a, L: X<&'a Nested<K>>>();
3939
|
4040
help: consider adding an explicit lifetime bound...
4141
|
42-
LL | trait X<K: 'a>: Sized {
43-
| ++++
42+
LL | fn foo<'a, L: X<&'a Nested<K>>>() where K: 'a;
43+
| +++++++++++
4444

4545
error[E0309]: the parameter type `Self` may not live long enough
4646
--> $DIR/lifetime-doesnt-live-long-enough.rs:28:19
4747
|
4848
LL | fn bar<'a, L: X<&'a Nested<Self>>>();
49-
| ^^^^^^^^^^^^^^^^^^^
49+
| ^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at
5050
|
51-
= help: consider adding an explicit lifetime bound `Self: 'a`...
52-
= note: ...so that the reference type `&'a Nested<Self>` does not outlive the data it points at
51+
help: consider adding an explicit lifetime bound...
52+
|
53+
LL | fn bar<'a, L: X<&'a Nested<Self>>>() where Self: 'a;
54+
| ++++++++++++++
5355

5456
error[E0309]: the parameter type `L` may not live long enough
5557
--> $DIR/lifetime-doesnt-live-long-enough.rs:32:22

tests/ui/lifetimes/suggest-introducing-and-adding-missing-lifetime.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#![allow(warnings)]
44

5-
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &() {
5+
fn no_restriction<'a, T: 'a>(x: &'a ()) -> &'a () {
66
with_restriction::<T>(x) //~ ERROR the parameter type `T` may not live long enough
77
}
88

0 commit comments

Comments
 (0)