From 1f853d25b8465e61209035393eebb765968e6173 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 23 Nov 2019 15:11:35 -0600 Subject: [PATCH 1/4] improve lifetime errors with implicit trait object lifetimes --- src/librustc/ty/sty.rs | 2 +- .../error_reporting/outlives_suggestion.rs | 15 ++------ .../error_reporting/region_name.rs | 36 +++++++++++++++---- .../issues/issue-63388-1.nll.stderr | 4 +-- ...s_pin_lifetime_impl_trait-async.nll.stderr | 6 ++-- ...pes_pin_lifetime_mismatch-async.nll.stderr | 17 ++++----- .../self/elision/lt-ref-self-async.nll.stderr | 36 +++++++++---------- .../elision/ref-mut-self-async.nll.stderr | 36 +++++++++---------- .../elision/ref-mut-struct-async.nll.stderr | 30 ++++++++-------- .../self/elision/ref-struct-async.nll.stderr | 30 ++++++++-------- 10 files changed, 114 insertions(+), 98 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index b72468a6ff98b..9b3ec59906289 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -69,7 +69,7 @@ pub enum BoundRegion { impl BoundRegion { pub fn is_named(&self) -> bool { match *self { - BoundRegion::BrNamed(..) => true, + BoundRegion::BrNamed(_, name) => name != kw::UnderscoreLifetime, _ => false, } } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs index c0cf4eb5285c9..907119dd2036f 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs @@ -78,17 +78,7 @@ impl OutlivesSuggestionBuilder<'a> { match name.source { RegionNameSource::NamedEarlyBoundRegion(..) | RegionNameSource::NamedFreeRegion(..) - | RegionNameSource::Static => { - // FIXME: This is a bit hacky. We should ideally have a semantic way for checking - // if the name is `'_`... - if name.name().with(|name| name != "'_") { - debug!("Region {:?} is suggestable", name); - true - } else { - debug!("Region {:?} is NOT suggestable", name); - false - } - } + | RegionNameSource::Static => true, // Don't give suggestions for upvars, closure return types, or other unnamable // regions. @@ -98,7 +88,8 @@ impl OutlivesSuggestionBuilder<'a> { | RegionNameSource::MatchedAdtAndSegment(..) | RegionNameSource::AnonRegionFromUpvar(..) | RegionNameSource::AnonRegionFromOutput(..) - | RegionNameSource::AnonRegionFromYieldTy(..) => { + | RegionNameSource::AnonRegionFromYieldTy(..) + | RegionNameSource::AnonRegionFromTraitObjAsync(..) => { debug!("Region {:?} is NOT suggestable", name); false } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index e59928987a03c..519991e815b27 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -55,7 +55,10 @@ crate enum RegionNameSource { AnonRegionFromUpvar(Span, String), /// The region corresponding to the return type of a closure. AnonRegionFromOutput(Span, String, String), + /// The region from a type yielded by a generator. AnonRegionFromYieldTy(Span, String), + /// An anonymous region from a trait object in an async fn. + AnonRegionFromTraitObjAsync(Span), } /// Records region names that have been assigned before so that we can use the same ones in later @@ -113,7 +116,8 @@ impl RegionName { RegionNameSource::MatchedAdtAndSegment(..) | RegionNameSource::AnonRegionFromUpvar(..) | RegionNameSource::AnonRegionFromOutput(..) | - RegionNameSource::AnonRegionFromYieldTy(..) => false, + RegionNameSource::AnonRegionFromYieldTy(..) | + RegionNameSource::AnonRegionFromTraitObjAsync(..) => false, } } @@ -137,7 +141,8 @@ impl RegionName { RegionNameSource::CannotMatchHirTy(span, type_name) => { diag.span_label(*span, format!("has type `{}`", type_name)); } - RegionNameSource::MatchedHirTy(span) => { + RegionNameSource::MatchedHirTy(span) | + RegionNameSource::AnonRegionFromTraitObjAsync(span) => { diag.span_label( *span, format!("let's call the lifetime of this reference `{}`", self), @@ -287,11 +292,30 @@ impl<'tcx> RegionInferenceContext<'tcx> { ty::ReFree(free_region) => match free_region.bound_region { ty::BoundRegion::BrNamed(_, name) => { + // Get the span to point to, even if we don't use the name. let span = self.get_named_span(tcx, error_region, name); - Some(RegionName { - name, - source: RegionNameSource::NamedFreeRegion(span), - }) + debug!("bound region named: {:?}, is_named: {:?}", + name, free_region.bound_region.is_named()); + + if free_region.bound_region.is_named() { + // A named region that is actually named. + Some(RegionName { + name, + source: RegionNameSource::NamedFreeRegion(span), + }) + } else { + // If we spuriously thought that the region is named, we should let the + // system generate a true name for error messages. Currently this can + // happen if we have an elided name in a trait object used in an async fn + // for example: the compiler will generate a region named `'_`, but + // reporting such a name is not actually useful, so we synthesize a name + // for it instead. + let name = self.synthesize_region_name(renctx); + Some(RegionName { + name, + source: RegionNameSource::AnonRegionFromTraitObjAsync(span), + }) + } } ty::BoundRegion::BrEnv => { diff --git a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr index 22610fe54a4cb..4ae3971e90eae 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr @@ -12,12 +12,12 @@ error: lifetime may not live long enough LL | async fn do_sth<'a>( | -- lifetime `'a` defined here LL | &'a self, foo: &dyn Foo - | - lifetime `'_` defined here + | - let's call the lifetime of this reference `'1` LL | ) -> &dyn Foo LL | / { LL | | foo LL | | } - | |_____^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'_` + | |_____^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` error: aborting due to 2 previous errors diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr index 713d4b759096e..5a63553adc5c8 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr @@ -2,11 +2,11 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } - | - ^^^^^^^^ returning this value requires that `'_` must outlive `'static` + | - ^^^^^^^^ returning this value requires that `'1` must outlive `'static` | | - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'_`, add `'_` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint | LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr index 7eec31d36e39e..b16c01de0afc1 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr @@ -10,19 +10,19 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } - | - ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75 | LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } - | - ^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58 @@ -36,8 +36,9 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } - | -- - lifetime `'_` defined here ^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'a` - | | + | -- - ^^^ function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | | | + | | let's call the lifetime of this reference `'1` | lifetime `'a` defined here error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr index 1288759703f69..0bf7f63ca2360 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr @@ -12,10 +12,10 @@ error: lifetime may not live long enough LL | async fn ref_self(&self, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/lt-ref-self-async.rs:18:48 @@ -31,10 +31,10 @@ error: lifetime may not live long enough LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/lt-ref-self-async.rs:22:57 @@ -50,10 +50,10 @@ error: lifetime may not live long enough LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/lt-ref-self-async.rs:26:57 @@ -69,10 +69,10 @@ error: lifetime may not live long enough LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/lt-ref-self-async.rs:30:66 @@ -88,10 +88,10 @@ error: lifetime may not live long enough LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/lt-ref-self-async.rs:34:62 @@ -107,10 +107,10 @@ error: lifetime may not live long enough LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 12 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr index 24e3f7a098fb1..f0987e0d03372 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr @@ -12,10 +12,10 @@ error: lifetime may not live long enough LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-self-async.rs:18:52 @@ -31,10 +31,10 @@ error: lifetime may not live long enough LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-self-async.rs:22:61 @@ -50,10 +50,10 @@ error: lifetime may not live long enough LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-self-async.rs:26:61 @@ -69,10 +69,10 @@ error: lifetime may not live long enough LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-self-async.rs:30:70 @@ -88,10 +88,10 @@ error: lifetime may not live long enough LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-self-async.rs:34:70 @@ -107,10 +107,10 @@ error: lifetime may not live long enough LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 12 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr index c0423d1d3e669..5c0261c2f60d2 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr @@ -12,10 +12,10 @@ error: lifetime may not live long enough LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-struct-async.rs:16:65 @@ -31,10 +31,10 @@ error: lifetime may not live long enough LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-struct-async.rs:20:65 @@ -50,10 +50,10 @@ error: lifetime may not live long enough LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-struct-async.rs:24:74 @@ -69,10 +69,10 @@ error: lifetime may not live long enough LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-mut-struct-async.rs:28:74 @@ -88,10 +88,10 @@ error: lifetime may not live long enough LL | async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 10 previous errors diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr index 6f413a7f49fb8..440facb9be180 100644 --- a/src/test/ui/self/elision/ref-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr @@ -12,10 +12,10 @@ error: lifetime may not live long enough LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-struct-async.rs:16:61 @@ -31,10 +31,10 @@ error: lifetime may not live long enough LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-struct-async.rs:20:61 @@ -50,10 +50,10 @@ error: lifetime may not live long enough LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-struct-async.rs:24:70 @@ -69,10 +69,10 @@ error: lifetime may not live long enough LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/ref-struct-async.rs:28:66 @@ -88,10 +88,10 @@ error: lifetime may not live long enough LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { | - | | - | lifetime `'_` defined here - | lifetime `'_` defined here + | let's call the lifetime of this reference `'1` + | let's call the lifetime of this reference `'2` LL | f - | ^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` + | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` error: aborting due to 10 previous errors From 59a768ce14ca8b439107dce0b575ee1c36244758 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sun, 24 Nov 2019 18:47:15 -0600 Subject: [PATCH 2/4] rename to AnonRegionFromAsyncFn --- .../error_reporting/outlives_suggestion.rs | 2 +- .../region_infer/error_reporting/region_name.rs | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs index 907119dd2036f..938059c2a923b 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/outlives_suggestion.rs @@ -89,7 +89,7 @@ impl OutlivesSuggestionBuilder<'a> { | RegionNameSource::AnonRegionFromUpvar(..) | RegionNameSource::AnonRegionFromOutput(..) | RegionNameSource::AnonRegionFromYieldTy(..) - | RegionNameSource::AnonRegionFromTraitObjAsync(..) => { + | RegionNameSource::AnonRegionFromAsyncFn(..) => { debug!("Region {:?} is NOT suggestable", name); false } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 519991e815b27..46c87db7af160 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -57,8 +57,8 @@ crate enum RegionNameSource { AnonRegionFromOutput(Span, String, String), /// The region from a type yielded by a generator. AnonRegionFromYieldTy(Span, String), - /// An anonymous region from a trait object in an async fn. - AnonRegionFromTraitObjAsync(Span), + /// An anonymous region from an async fn. + AnonRegionFromAsyncFn(Span), } /// Records region names that have been assigned before so that we can use the same ones in later @@ -117,7 +117,7 @@ impl RegionName { RegionNameSource::AnonRegionFromUpvar(..) | RegionNameSource::AnonRegionFromOutput(..) | RegionNameSource::AnonRegionFromYieldTy(..) | - RegionNameSource::AnonRegionFromTraitObjAsync(..) => false, + RegionNameSource::AnonRegionFromAsyncFn(..) => false, } } @@ -142,7 +142,7 @@ impl RegionName { diag.span_label(*span, format!("has type `{}`", type_name)); } RegionNameSource::MatchedHirTy(span) | - RegionNameSource::AnonRegionFromTraitObjAsync(span) => { + RegionNameSource::AnonRegionFromAsyncFn(span) => { diag.span_label( *span, format!("let's call the lifetime of this reference `{}`", self), @@ -306,14 +306,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { } else { // If we spuriously thought that the region is named, we should let the // system generate a true name for error messages. Currently this can - // happen if we have an elided name in a trait object used in an async fn - // for example: the compiler will generate a region named `'_`, but - // reporting such a name is not actually useful, so we synthesize a name - // for it instead. + // happen if we have an elided name in an async fn for example: the + // compiler will generate a region named `'_`, but reporting such a name is + // not actually useful, so we synthesize a name for it instead. let name = self.synthesize_region_name(renctx); Some(RegionName { name, - source: RegionNameSource::AnonRegionFromTraitObjAsync(span), + source: RegionNameSource::AnonRegionFromAsyncFn(span), }) } } From 05db660d399d5f53adf8f6bafd11c03fb9cdfd52 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Mon, 25 Nov 2019 12:36:53 -0600 Subject: [PATCH 3/4] remove get_named_span --- .../error_reporting/region_name.rs | 44 +++---------------- ...pes_pin_lifetime_mismatch-async.nll.stderr | 12 ++--- .../self/elision/lt-ref-self-async.nll.stderr | 18 +++----- .../elision/ref-mut-self-async.nll.stderr | 18 +++----- .../elision/ref-mut-struct-async.nll.stderr | 15 +++---- .../self/elision/ref-struct-async.nll.stderr | 15 +++---- 6 files changed, 33 insertions(+), 89 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index 46c87db7af160..b775ffdad1b55 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -13,13 +13,13 @@ use rustc::hir::def_id::DefId; use rustc::infer::InferCtxt; use rustc::mir::{Local, Body}; use rustc::ty::subst::{SubstsRef, GenericArgKind}; -use rustc::ty::{self, RegionKind, RegionVid, Ty, TyCtxt}; +use rustc::ty::{self, RegionVid, Ty, TyCtxt}; use rustc::ty::print::RegionHighlightMode; use rustc_index::vec::IndexVec; use rustc_errors::DiagnosticBuilder; use syntax::symbol::kw; use rustc_data_structures::fx::FxHashMap; -use syntax_pos::{Span, symbol::Symbol}; +use syntax_pos::{Span, symbol::Symbol, DUMMY_SP}; /// A name for a particular region used in emitting diagnostics. This name could be a generated /// name like `'1`, a name used by the user like `'a`, or a name like `'static`. @@ -275,7 +275,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { match error_region { ty::ReEarlyBound(ebr) => { if ebr.has_name() { - let span = self.get_named_span(tcx, error_region, ebr.name); + let span = tcx.hir().span_if_local(ebr.def_id).unwrap_or(DUMMY_SP); Some(RegionName { name: ebr.name, source: RegionNameSource::NamedEarlyBoundRegion(span), @@ -291,9 +291,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { }), ty::ReFree(free_region) => match free_region.bound_region { - ty::BoundRegion::BrNamed(_, name) => { + ty::BoundRegion::BrNamed(region_def_id, name) => { // Get the span to point to, even if we don't use the name. - let span = self.get_named_span(tcx, error_region, name); + let span = tcx.hir().span_if_local(region_def_id).unwrap_or(DUMMY_SP); debug!("bound region named: {:?}, is_named: {:?}", name, free_region.bound_region.is_named()); @@ -373,40 +373,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// Gets a span of a named region to provide context for error messages that - /// mention that span, for example: - /// - /// ``` - /// | - /// | fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) - /// | -- -- lifetime `'b` defined here - /// | | - /// | lifetime `'a` defined here - /// | - /// | with_signature(cell, t, |cell, t| require(cell, t)); - /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'b` must - /// | outlive `'a` - /// ``` - fn get_named_span( - &self, - tcx: TyCtxt<'tcx>, - error_region: &RegionKind, - name: Symbol, - ) -> Span { - let scope = error_region.free_region_binding_scope(tcx); - let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID); - - let span = tcx.sess.source_map().def_span(tcx.hir().span(node)); - if let Some(param) = tcx.hir() - .get_generics(scope) - .and_then(|generics| generics.get_named(name)) - { - param.span - } else { - span - } - } - /// Finds an argument that contains `fr` and label it with a fully /// elaborated type, returning something like `'1`. Result looks /// like: diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr index b16c01de0afc1..b05940fd273a1 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr @@ -10,18 +10,18 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } - | - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` - | | - | let's call the lifetime of this reference `'1` + | - - ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | | + | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75 | LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } - | - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` - | | - | let's call the lifetime of this reference `'1` + | - - ^^^^^^^^^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | | | + | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr index 0bf7f63ca2360..8dd823a220497 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr @@ -10,9 +10,8 @@ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:13:9 | LL | async fn ref_self(&self, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -29,9 +28,8 @@ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:19:9 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -48,9 +46,8 @@ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:23:9 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -67,9 +64,8 @@ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:27:9 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -86,9 +82,8 @@ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:31:9 | LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -105,9 +100,8 @@ error: lifetime may not live long enough --> $DIR/lt-ref-self-async.rs:35:9 | LL | async fn box_pin_Self(self: Box>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr index f0987e0d03372..768f532c18317 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr @@ -10,9 +10,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:13:9 | LL | async fn ref_self(&mut self, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -29,9 +28,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:19:9 | LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -48,9 +46,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:23:9 | LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -67,9 +64,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:27:9 | LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -86,9 +82,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:31:9 | LL | async fn box_box_ref_Self(self: Box>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -105,9 +100,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-self-async.rs:35:9 | LL | async fn box_pin_ref_Self(self: Box>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr index 5c0261c2f60d2..9e26e411d30bd 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr @@ -10,9 +10,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:13:9 | LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -29,9 +28,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:17:9 | LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -48,9 +46,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:21:9 | LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -67,9 +64,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:25:9 | LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -86,9 +82,8 @@ error: lifetime may not live long enough --> $DIR/ref-mut-struct-async.rs:29:9 | LL | async fn box_pin_ref_Struct(self: Box>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr index 440facb9be180..cbf051205ed96 100644 --- a/src/test/ui/self/elision/ref-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr @@ -10,9 +10,8 @@ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:13:9 | LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -29,9 +28,8 @@ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:17:9 | LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -48,9 +46,8 @@ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:21:9 | LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -67,9 +64,8 @@ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:25:9 | LL | async fn box_box_ref_Struct(self: Box>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` @@ -86,9 +82,8 @@ error: lifetime may not live long enough --> $DIR/ref-struct-async.rs:29:9 | LL | async fn box_pin_Struct(self: Box>, f: &u32) -> &u32 { - | - + | - - let's call the lifetime of this reference `'1` | | - | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` LL | f | ^ function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` From 2a86b6cb33536efe5d4d10764b04542205abe581 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Fri, 29 Nov 2019 11:07:01 -0600 Subject: [PATCH 4/4] minor fix --- .../nll/region_infer/error_reporting/region_name.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs index b775ffdad1b55..0f5d1c5edc498 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs @@ -121,10 +121,6 @@ impl RegionName { } } - crate fn name(&self) -> Symbol { - self.name - } - crate fn highlight_region_name(&self, diag: &mut DiagnosticBuilder<'_>) { match &self.source { RegionNameSource::NamedFreeRegion(span) @@ -309,7 +305,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // happen if we have an elided name in an async fn for example: the // compiler will generate a region named `'_`, but reporting such a name is // not actually useful, so we synthesize a name for it instead. - let name = self.synthesize_region_name(renctx); + let name = renctx.synthesize_region_name(); Some(RegionName { name, source: RegionNameSource::AnonRegionFromAsyncFn(span),