Skip to content

Commit 1f853d2

Browse files
committed
improve lifetime errors with implicit trait object lifetimes
1 parent c4375c9 commit 1f853d2

File tree

10 files changed

+114
-98
lines changed

10 files changed

+114
-98
lines changed

src/librustc/ty/sty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub enum BoundRegion {
6969
impl BoundRegion {
7070
pub fn is_named(&self) -> bool {
7171
match *self {
72-
BoundRegion::BrNamed(..) => true,
72+
BoundRegion::BrNamed(_, name) => name != kw::UnderscoreLifetime,
7373
_ => false,
7474
}
7575
}

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,7 @@ impl OutlivesSuggestionBuilder<'a> {
7878
match name.source {
7979
RegionNameSource::NamedEarlyBoundRegion(..)
8080
| RegionNameSource::NamedFreeRegion(..)
81-
| RegionNameSource::Static => {
82-
// FIXME: This is a bit hacky. We should ideally have a semantic way for checking
83-
// if the name is `'_`...
84-
if name.name().with(|name| name != "'_") {
85-
debug!("Region {:?} is suggestable", name);
86-
true
87-
} else {
88-
debug!("Region {:?} is NOT suggestable", name);
89-
false
90-
}
91-
}
81+
| RegionNameSource::Static => true,
9282

9383
// Don't give suggestions for upvars, closure return types, or other unnamable
9484
// regions.
@@ -98,7 +88,8 @@ impl OutlivesSuggestionBuilder<'a> {
9888
| RegionNameSource::MatchedAdtAndSegment(..)
9989
| RegionNameSource::AnonRegionFromUpvar(..)
10090
| RegionNameSource::AnonRegionFromOutput(..)
101-
| RegionNameSource::AnonRegionFromYieldTy(..) => {
91+
| RegionNameSource::AnonRegionFromYieldTy(..)
92+
| RegionNameSource::AnonRegionFromTraitObjAsync(..) => {
10293
debug!("Region {:?} is NOT suggestable", name);
10394
false
10495
}

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ crate enum RegionNameSource {
5555
AnonRegionFromUpvar(Span, String),
5656
/// The region corresponding to the return type of a closure.
5757
AnonRegionFromOutput(Span, String, String),
58+
/// The region from a type yielded by a generator.
5859
AnonRegionFromYieldTy(Span, String),
60+
/// An anonymous region from a trait object in an async fn.
61+
AnonRegionFromTraitObjAsync(Span),
5962
}
6063

6164
/// Records region names that have been assigned before so that we can use the same ones in later
@@ -113,7 +116,8 @@ impl RegionName {
113116
RegionNameSource::MatchedAdtAndSegment(..) |
114117
RegionNameSource::AnonRegionFromUpvar(..) |
115118
RegionNameSource::AnonRegionFromOutput(..) |
116-
RegionNameSource::AnonRegionFromYieldTy(..) => false,
119+
RegionNameSource::AnonRegionFromYieldTy(..) |
120+
RegionNameSource::AnonRegionFromTraitObjAsync(..) => false,
117121
}
118122
}
119123

@@ -137,7 +141,8 @@ impl RegionName {
137141
RegionNameSource::CannotMatchHirTy(span, type_name) => {
138142
diag.span_label(*span, format!("has type `{}`", type_name));
139143
}
140-
RegionNameSource::MatchedHirTy(span) => {
144+
RegionNameSource::MatchedHirTy(span) |
145+
RegionNameSource::AnonRegionFromTraitObjAsync(span) => {
141146
diag.span_label(
142147
*span,
143148
format!("let's call the lifetime of this reference `{}`", self),
@@ -287,11 +292,30 @@ impl<'tcx> RegionInferenceContext<'tcx> {
287292

288293
ty::ReFree(free_region) => match free_region.bound_region {
289294
ty::BoundRegion::BrNamed(_, name) => {
295+
// Get the span to point to, even if we don't use the name.
290296
let span = self.get_named_span(tcx, error_region, name);
291-
Some(RegionName {
292-
name,
293-
source: RegionNameSource::NamedFreeRegion(span),
294-
})
297+
debug!("bound region named: {:?}, is_named: {:?}",
298+
name, free_region.bound_region.is_named());
299+
300+
if free_region.bound_region.is_named() {
301+
// A named region that is actually named.
302+
Some(RegionName {
303+
name,
304+
source: RegionNameSource::NamedFreeRegion(span),
305+
})
306+
} else {
307+
// If we spuriously thought that the region is named, we should let the
308+
// system generate a true name for error messages. Currently this can
309+
// happen if we have an elided name in a trait object used in an async fn
310+
// for example: the compiler will generate a region named `'_`, but
311+
// reporting such a name is not actually useful, so we synthesize a name
312+
// for it instead.
313+
let name = self.synthesize_region_name(renctx);
314+
Some(RegionName {
315+
name,
316+
source: RegionNameSource::AnonRegionFromTraitObjAsync(span),
317+
})
318+
}
295319
}
296320

297321
ty::BoundRegion::BrEnv => {

src/test/ui/async-await/issues/issue-63388-1.nll.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ error: lifetime may not live long enough
1212
LL | async fn do_sth<'a>(
1313
| -- lifetime `'a` defined here
1414
LL | &'a self, foo: &dyn Foo
15-
| - lifetime `'_` defined here
15+
| - let's call the lifetime of this reference `'1`
1616
LL | ) -> &dyn Foo
1717
LL | / {
1818
LL | | foo
1919
LL | | }
20-
| |_____^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'_`
20+
| |_____^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1`
2121

2222
error: aborting due to 2 previous errors
2323

src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ error: lifetime may not live long enough
22
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48
33
|
44
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
5-
| - ^^^^^^^^ returning this value requires that `'_` must outlive `'static`
5+
| - ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
66
| |
7-
| lifetime `'_` defined here
7+
| let's call the lifetime of this reference `'1`
88
|
9-
help: to allow this `impl Trait` to capture borrowed data with lifetime `'_`, add `'_` as a constraint
9+
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint
1010
|
1111
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
1212
| ^^^^^^^^^^^^^^^

src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ error: lifetime may not live long enough
1010
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
1111
|
1212
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
13-
| - ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
13+
| - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
1414
| |
15-
| lifetime `'_` defined here
16-
| lifetime `'_` defined here
15+
| let's call the lifetime of this reference `'1`
16+
| let's call the lifetime of this reference `'2`
1717

1818
error: lifetime may not live long enough
1919
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75
2020
|
2121
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
22-
| - ^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
22+
| - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
2323
| |
24-
| lifetime `'_` defined here
25-
| lifetime `'_` defined here
24+
| let's call the lifetime of this reference `'1`
25+
| let's call the lifetime of this reference `'2`
2626

2727
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
2828
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58
@@ -36,8 +36,9 @@ error: lifetime may not live long enough
3636
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
3737
|
3838
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
39-
| -- - lifetime `'_` defined here ^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'a`
40-
| |
39+
| -- - ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
40+
| | |
41+
| | let's call the lifetime of this reference `'1`
4142
| lifetime `'a` defined here
4243

4344
error: aborting due to 5 previous errors

src/test/ui/self/elision/lt-ref-self-async.nll.stderr

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ error: lifetime may not live long enough
1212
LL | async fn ref_self(&self, f: &u32) -> &u32 {
1313
| -
1414
| |
15-
| lifetime `'_` defined here
16-
| lifetime `'_` defined here
15+
| let's call the lifetime of this reference `'1`
16+
| let's call the lifetime of this reference `'2`
1717
LL | f
18-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
18+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
1919

2020
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
2121
--> $DIR/lt-ref-self-async.rs:18:48
@@ -31,10 +31,10 @@ error: lifetime may not live long enough
3131
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
3232
| -
3333
| |
34-
| lifetime `'_` defined here
35-
| lifetime `'_` defined here
34+
| let's call the lifetime of this reference `'1`
35+
| let's call the lifetime of this reference `'2`
3636
LL | f
37-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
37+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
3838

3939
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
4040
--> $DIR/lt-ref-self-async.rs:22:57
@@ -50,10 +50,10 @@ error: lifetime may not live long enough
5050
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
5151
| -
5252
| |
53-
| lifetime `'_` defined here
54-
| lifetime `'_` defined here
53+
| let's call the lifetime of this reference `'1`
54+
| let's call the lifetime of this reference `'2`
5555
LL | f
56-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
56+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
5757

5858
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
5959
--> $DIR/lt-ref-self-async.rs:26:57
@@ -69,10 +69,10 @@ error: lifetime may not live long enough
6969
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
7070
| -
7171
| |
72-
| lifetime `'_` defined here
73-
| lifetime `'_` defined here
72+
| let's call the lifetime of this reference `'1`
73+
| let's call the lifetime of this reference `'2`
7474
LL | f
75-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
75+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
7676

7777
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
7878
--> $DIR/lt-ref-self-async.rs:30:66
@@ -88,10 +88,10 @@ error: lifetime may not live long enough
8888
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
8989
| -
9090
| |
91-
| lifetime `'_` defined here
92-
| lifetime `'_` defined here
91+
| let's call the lifetime of this reference `'1`
92+
| let's call the lifetime of this reference `'2`
9393
LL | f
94-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
94+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
9595

9696
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
9797
--> $DIR/lt-ref-self-async.rs:34:62
@@ -107,10 +107,10 @@ error: lifetime may not live long enough
107107
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
108108
| -
109109
| |
110-
| lifetime `'_` defined here
111-
| lifetime `'_` defined here
110+
| let's call the lifetime of this reference `'1`
111+
| let's call the lifetime of this reference `'2`
112112
LL | f
113-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
113+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
114114

115115
error: aborting due to 12 previous errors
116116

src/test/ui/self/elision/ref-mut-self-async.nll.stderr

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ error: lifetime may not live long enough
1212
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
1313
| -
1414
| |
15-
| lifetime `'_` defined here
16-
| lifetime `'_` defined here
15+
| let's call the lifetime of this reference `'1`
16+
| let's call the lifetime of this reference `'2`
1717
LL | f
18-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
18+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
1919

2020
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
2121
--> $DIR/ref-mut-self-async.rs:18:52
@@ -31,10 +31,10 @@ error: lifetime may not live long enough
3131
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
3232
| -
3333
| |
34-
| lifetime `'_` defined here
35-
| lifetime `'_` defined here
34+
| let's call the lifetime of this reference `'1`
35+
| let's call the lifetime of this reference `'2`
3636
LL | f
37-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
37+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
3838

3939
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
4040
--> $DIR/ref-mut-self-async.rs:22:61
@@ -50,10 +50,10 @@ error: lifetime may not live long enough
5050
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
5151
| -
5252
| |
53-
| lifetime `'_` defined here
54-
| lifetime `'_` defined here
53+
| let's call the lifetime of this reference `'1`
54+
| let's call the lifetime of this reference `'2`
5555
LL | f
56-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
56+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
5757

5858
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
5959
--> $DIR/ref-mut-self-async.rs:26:61
@@ -69,10 +69,10 @@ error: lifetime may not live long enough
6969
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
7070
| -
7171
| |
72-
| lifetime `'_` defined here
73-
| lifetime `'_` defined here
72+
| let's call the lifetime of this reference `'1`
73+
| let's call the lifetime of this reference `'2`
7474
LL | f
75-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
75+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
7676

7777
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
7878
--> $DIR/ref-mut-self-async.rs:30:70
@@ -88,10 +88,10 @@ error: lifetime may not live long enough
8888
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
8989
| -
9090
| |
91-
| lifetime `'_` defined here
92-
| lifetime `'_` defined here
91+
| let's call the lifetime of this reference `'1`
92+
| let's call the lifetime of this reference `'2`
9393
LL | f
94-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
94+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
9595

9696
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
9797
--> $DIR/ref-mut-self-async.rs:34:70
@@ -107,10 +107,10 @@ error: lifetime may not live long enough
107107
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
108108
| -
109109
| |
110-
| lifetime `'_` defined here
111-
| lifetime `'_` defined here
110+
| let's call the lifetime of this reference `'1`
111+
| let's call the lifetime of this reference `'2`
112112
LL | f
113-
| ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_`
113+
| ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
114114

115115
error: aborting due to 12 previous errors
116116

0 commit comments

Comments
 (0)