From d10fe26f39983c782f1a37a447f2c10c2ef561ba Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Sun, 10 Oct 2021 10:37:57 +0000 Subject: [PATCH 01/14] Point at capture points for non-`'static` reference crossing a `yield` point ``` error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/issue-72312.rs:10:24 | LL | pub async fn start(&self) { | ^^^^^ this data with an anonymous lifetime `'_`... ... LL | require_static(async move { | -------------- ...is required to live as long as `'static` here... LL | &self; | ----- ...and is captured here | note: `'static` lifetime requirement introduced by this trait bound --> $DIR/issue-72312.rs:2:22 | LL | fn require_static(val: T) -> T { | ^^^^^^^ error: aborting due to previous error For more information about this error, try `rustc --explain E0759`. ``` Fix #72312. --- .../src/diagnostics/bound_region_errors.rs | 1 + .../src/infer/error_reporting/mod.rs | 3 +- .../error_reporting/nice_region_error/mod.rs | 2 +- .../nice_region_error/placeholder_error.rs | 4 ++ .../nice_region_error/static_impl_trait.rs | 69 ++++++++++++++++--- .../trait_impl_difference.rs | 1 + .../src/infer/lexical_region_resolve/mod.rs | 32 +++++++-- .../ui/async-await/issues/issue-62097.stderr | 18 +++-- src/test/ui/async-await/issues/issue-72312.rs | 19 +++++ .../ui/async-await/issues/issue-72312.stderr | 20 ++++++ .../trait-upcasting/type-checking-test-4.rs | 18 +++++ .../type-checking-test-4.stderr | 48 ++++++++++++- 12 files changed, 212 insertions(+), 23 deletions(-) create mode 100644 src/test/ui/async-await/issues/issue-72312.rs create mode 100644 src/test/ui/async-await/issues/issue-72312.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 1bc9f8cf3cc..881ebed6029 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -368,6 +368,7 @@ fn try_extract_error_from_fulfill_cx<'tcx>( error_region, cause.clone(), placeholder_region, + vec![], ), ), (Some(error_region), _) => NiceRegionError::new( diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 85226e60bdb..c3f2213229a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -384,6 +384,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { sub_r, sup_origin, sup_r, + _, ) => { if sub_r.is_placeholder() { self.report_placeholder_failure(sub_origin, sub_r, sup_r).emit(); @@ -464,7 +465,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { errors.sort_by_key(|u| match *u { RegionResolutionError::ConcreteFailure(ref sro, _, _) => sro.span(), RegionResolutionError::GenericBoundFailure(ref sro, _, _) => sro.span(), - RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _) => rvo.span(), + RegionResolutionError::SubSupConflict(_, ref rvo, _, _, _, _, _) => rvo.span(), RegionResolutionError::UpperBoundUniverseConflict(_, ref rvo, _, _, _) => rvo.span(), }); errors diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs index 6a330977002..fd295b74342 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/mod.rs @@ -67,7 +67,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> { pub fn regions(&self) -> Option<(Span, ty::Region<'tcx>, ty::Region<'tcx>)> { match (&self.error, self.regions) { (Some(ConcreteFailure(origin, sub, sup)), None) => Some((origin.span(), sub, sup)), - (Some(SubSupConflict(_, _, origin, sub, _, sup)), None) => { + (Some(SubSupConflict(_, _, origin, sub, _, sup, _)), None) => { Some((origin.span(), sub, sup)) } (None, Some((span, sub, sup))) => Some((span, sub, sup)), diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs index 4aecc2f40b8..1a4a2803821 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -34,6 +34,7 @@ impl NiceRegionError<'me, 'tcx> { sub_placeholder @ ty::RePlaceholder(_), _, sup_placeholder @ ty::RePlaceholder(_), + _, )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, @@ -49,6 +50,7 @@ impl NiceRegionError<'me, 'tcx> { sub_placeholder @ ty::RePlaceholder(_), _, _, + _, )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, @@ -64,6 +66,7 @@ impl NiceRegionError<'me, 'tcx> { _, _, sup_placeholder @ ty::RePlaceholder(_), + _, )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, @@ -79,6 +82,7 @@ impl NiceRegionError<'me, 'tcx> { _, SubregionOrigin::Subtype(box TypeTrace { cause, values }), sup_placeholder @ ty::RePlaceholder(_), + _, )) => self.try_report_trait_placeholder_mismatch( Some(self.tcx().mk_region(ty::ReVar(*vid))), cause, diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 2aaebed28ce..c7ba5087b8c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -23,7 +23,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { pub(super) fn try_report_static_impl_trait(&self) -> Option { debug!("try_report_static_impl_trait(error={:?})", self.error); let tcx = self.tcx(); - let (var_origin, sub_origin, sub_r, sup_origin, sup_r) = match self.error.as_ref()? { + let (var_origin, sub_origin, sub_r, sup_origin, sup_r, spans) = match self.error.as_ref()? { RegionResolutionError::SubSupConflict( _, var_origin, @@ -31,8 +31,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { sub_r, sup_origin, sup_r, + spans, ) if **sub_r == RegionKind::ReStatic => { - (var_origin, sub_origin, sub_r, sup_origin, sup_r) + (var_origin, sub_origin, sub_r, sup_origin, sup_r, spans) } RegionResolutionError::ConcreteFailure( SubregionOrigin::Subtype(box TypeTrace { cause, .. }), @@ -123,15 +124,31 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { param_name, lifetime, ); - err.span_label(param.param_ty_span, &format!("this data with {}...", lifetime)); + + let (mention_capture, capture_point) = if sup_origin.span().overlaps(param.param_ty_span) { + // Account for `async fn` like in `async-await/issues/issue-62097.rs`. + // The desugaring of `async `fn`s causes `sup_origin` and `param` to point at the same + // place (but with different `ctxt`, hence `overlaps` instead of `==` above). + // + // This avoids the following: + // + // LL | pub async fn run_dummy_fn(&self) { + // | ^^^^^ + // | | + // | this data with an anonymous lifetime `'_`... + // | ...is captured here... + (false, sup_origin.span()) + } else { + (true, param.param_ty_span) + }; + err.span_label(capture_point, &format!("this data with {}...", lifetime)); + debug!("try_report_static_impl_trait: param_info={:?}", param); // We try to make the output have fewer overlapping spans if possible. if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span())) && sup_origin.span() != return_sp { - // FIXME: account for `async fn` like in `async-await/issues/issue-62097.rs` - // Customize the spans and labels depending on their relative order so // that split sentences flow correctly. if sup_origin.span().overlaps(return_sp) && sp == sup_origin.span() { @@ -152,11 +169,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // | ---- ^ err.span_label( sup_origin.span(), - "...is captured here, requiring it to live as long as `'static`", + &format!( + "...is captured here, requiring it to live as long as `'static`{}", + if spans.is_empty() { "" } else { "..." }, + ), ); } else { - err.span_label(sup_origin.span(), "...is captured here..."); - if return_sp < sup_origin.span() { + if return_sp < sup_origin.span() && mention_capture { + err.span_label(sup_origin.span(), "...is captured here..."); err.span_note( return_sp, "...and is required to live as long as `'static` here", @@ -164,17 +184,46 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } else { err.span_label( return_sp, - "...and is required to live as long as `'static` here", + &format!( + "...is required to live as long as `'static` here{}", + if spans.is_empty() { "" } else { "..." }, + ), ); + if mention_capture { + let span = sup_origin.span(); + let msg = if spans.iter().any(|sp| *sp > span) { + "...is captured here..." + } else { + "...and is captured here" + }; + err.span_label(span, msg); + } } } } else { err.span_label( return_sp, - "...is captured and required to live as long as `'static` here", + &format!( + "...is captured and required to live as long as `'static` here{}", + if spans.is_empty() { "" } else { "..." }, + ), ); } + for span in spans { + let msg = + format!("...and is captured here{}", if mention_capture { " too" } else { "" }); + if span.overlaps(return_sp) { + err.span_note(*span, &msg); + } else { + err.span_label(*span, &msg); + } + } + + if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin { + err.span_note(*bound, "`'static` lifetime requirement introduced by this trait bound"); + } + let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); let mut override_error_code = None; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index cfa79213c80..452ca5eeabd 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -28,6 +28,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { _sub, sup_origin, _sup, + _, ) = error.clone() { if let (&Subtype(ref sup_trace), &Subtype(ref sub_trace)) = (&sup_origin, &sub_origin) { diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 4c9dcab26b1..14f6c72bb1c 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ReEarlyBound, ReEmpty, ReErased, ReFree, ReStatic}; use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar}; use rustc_middle::ty::{Region, RegionVid}; +use rustc_span::Span; use std::fmt; /// This function performs lexical region resolution given a complete @@ -96,6 +97,7 @@ pub enum RegionResolutionError<'tcx> { Region<'tcx>, SubregionOrigin<'tcx>, Region<'tcx>, + Vec, ), /// Indicates a `'b: 'a` constraint where `'a` is in a universe that @@ -144,8 +146,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { let graph = self.construct_graph(); self.expand_givens(&graph); self.expansion(&mut var_data); - self.collect_errors(&mut var_data, errors); - self.collect_var_errors(&var_data, &graph, errors); + let captures = self.collect_errors(&mut var_data, errors); + self.collect_var_errors(&var_data, &graph, errors, captures); var_data } @@ -443,9 +445,16 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { &self, var_data: &mut LexicalRegionResolutions<'tcx>, errors: &mut Vec>, - ) { + ) -> Vec { + let mut captures = vec![]; + for (constraint, origin) in &self.data.constraints { debug!(?constraint, ?origin); + if let (Constraint::VarSubVar(_, _), SubregionOrigin::DataBorrowed(_, sp)) = + (constraint, origin) + { + captures.push(*sp); + } match *constraint { Constraint::RegSubVar(..) | Constraint::VarSubVar(..) => { // Expansion will ensure that these constraints hold. Ignore. @@ -515,6 +524,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { sub, )); } + captures } /// Go over the variables that were declared to be error variables @@ -524,6 +534,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { var_data: &LexicalRegionResolutions<'tcx>, graph: &RegionGraph<'tcx>, errors: &mut Vec>, + captures: Vec, ) { debug!("collect_var_errors, var_data = {:#?}", var_data.values); @@ -567,7 +578,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // if this rule starts to create problems we'll // have to revisit this portion of the code and // think hard about it. =) -- nikomatsakis - self.collect_error_for_expanding_node(graph, &mut dup_vec, node_vid, errors); + self.collect_error_for_expanding_node( + graph, + &mut dup_vec, + node_vid, + errors, + &captures, + ); } } } @@ -621,6 +638,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { dup_vec: &mut IndexVec>, node_idx: RegionVid, errors: &mut Vec>, + captures: &[Span], ) { // Errors in expanding nodes result from a lower-bound that is // not contained by an upper-bound. @@ -667,6 +685,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { sup: {:?}", origin, node_idx, lower_bound.region, upper_bound.region ); + + let mut capture_spans: Vec = captures.iter().cloned().collect(); + // Below, one span expects `&Span` and the other `&mut Span`, hence the dupes. + capture_spans.sort_by_key(|span| (span.lo(), span.hi())); + capture_spans.dedup_by_key(|span| (span.lo(), span.hi())); errors.push(RegionResolutionError::SubSupConflict( node_idx, origin, @@ -674,6 +697,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { lower_bound.region, upper_bound.origin.clone(), upper_bound.region, + capture_spans, )); return; } diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index 56a28d904b9..bb329a4a0c2 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -2,12 +2,20 @@ error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `' --> $DIR/issue-62097.rs:12:31 | LL | pub async fn run_dummy_fn(&self) { - | ^^^^^ - | | - | this data with an anonymous lifetime `'_`... - | ...is captured here... + | ^^^^^ this data with an anonymous lifetime `'_`... LL | foo(|| self.bar()).await; - | --- ...and is required to live as long as `'static` here + | --- ...is required to live as long as `'static` here... + | +note: ...and is captured here + --> $DIR/issue-62097.rs:13:9 + | +LL | foo(|| self.bar()).await; + | ^^^^^^^^^^^^^^^^^^^^^^^^ +note: `'static` lifetime requirement introduced by this trait bound + --> $DIR/issue-62097.rs:4:19 + | +LL | F: FnOnce() + 'static + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/async-await/issues/issue-72312.rs b/src/test/ui/async-await/issues/issue-72312.rs new file mode 100644 index 00000000000..d33685e02f1 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-72312.rs @@ -0,0 +1,19 @@ +// edition:2018 +fn require_static(val: T) -> T { + //~^ NOTE 'static` lifetime requirement introduced by this trait bound + val +} + +struct Problem; + +impl Problem { + pub async fn start(&self) { //~ ERROR E0759 + //~^ NOTE this data with an anonymous lifetime `'_` + //~| NOTE in this expansion of desugaring of `async` block or function + require_static(async move { //~ NOTE ...is required to live as long as `'static` here + &self; //~ NOTE ...and is captured here + }); + } +} + +fn main() {} diff --git a/src/test/ui/async-await/issues/issue-72312.stderr b/src/test/ui/async-await/issues/issue-72312.stderr new file mode 100644 index 00000000000..ee5ee6f0f93 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-72312.stderr @@ -0,0 +1,20 @@ +error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/issue-72312.rs:10:24 + | +LL | pub async fn start(&self) { + | ^^^^^ this data with an anonymous lifetime `'_`... +... +LL | require_static(async move { + | -------------- ...is required to live as long as `'static` here... +LL | &self; + | ----- ...and is captured here + | +note: `'static` lifetime requirement introduced by this trait bound + --> $DIR/issue-72312.rs:2:22 + | +LL | fn require_static(val: T) -> T { + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0759`. diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs index 9b27fd46f7a..95698fd1e1a 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs @@ -29,4 +29,22 @@ fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { y.get_b() // ERROR } +fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + <_ as Bar>::get_b(x) // ERROR + //~^ ERROR `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement +} + +fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + <_ as Bar<'_, '_>>::get_b(x) // ERROR + //~^ ERROR `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement +} + +fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + let y = x as &dyn Bar<'_, '_>; + //~^ ERROR `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement + y.get_b(); // ERROR + let z = y; + z.get_b() // ERROR +} + fn main() {} diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr index 4967f3dc2c8..04560ea4e29 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -39,9 +39,53 @@ LL | let y = x as &dyn Bar<'_, '_>; | ...is captured here... LL | LL | y.get_b() // ERROR - | --------- ...and is required to live as long as `'static` here + | --------- ...is required to live as long as `'static` here... + | +note: ...and is captured here too + --> $DIR/type-checking-test-4.rs:29:5 + | +LL | y.get_b() // ERROR + | ^ -error: aborting due to 3 previous errors +error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/type-checking-test-4.rs:33:5 + | +LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | ------------ this data with lifetime `'a`... +LL | <_ as Bar>::get_b(x) // ERROR + | ^^^^^^^^^^^^^^^^^ ...is captured here, requiring it to live as long as `'static` + +error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/type-checking-test-4.rs:38:15 + | +LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | ------------ this data with lifetime `'a`... +LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR + | ----------^^---------------- ...is captured and required to live as long as `'static` here + +error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/type-checking-test-4.rs:43:27 + | +LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | ------------ this data with lifetime `'a`... +LL | let y = x as &dyn Bar<'_, '_>; + | - ^^ + | | + | ...is captured here... +LL | +LL | y.get_b(); // ERROR + | - ...and is captured here too +LL | let z = y; +LL | z.get_b() // ERROR + | --------- ...is required to live as long as `'static` here... + | +note: ...and is captured here too + --> $DIR/type-checking-test-4.rs:47:5 + | +LL | z.get_b() // ERROR + | ^ + +error: aborting due to 6 previous errors Some errors have detailed explanations: E0308, E0759. For more information about an error, try `rustc --explain E0308`. From dd81e984660bf4273470d336eaed27f9e062ce1c Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Mon, 11 Oct 2021 19:20:13 +0000 Subject: [PATCH 02/14] Clean up visual output logic --- .../nice_region_error/static_impl_trait.rs | 92 +++++-------------- ...ject-fn-ret-contravariant.transmute.stderr | 2 +- .../project-fn-ret-invariant.transmute.stderr | 2 +- .../ui/async-await/issues/issue-62097.stderr | 8 +- src/test/ui/async-await/issues/issue-72312.rs | 6 +- .../ui/async-await/issues/issue-72312.stderr | 11 ++- .../must_outlive_least_region_or_bound.stderr | 10 +- src/test/ui/issues/issue-16922.stderr | 2 +- .../region-object-lifetime-in-coercion.stderr | 6 +- .../regions-close-object-into-object-2.stderr | 2 +- .../regions-close-object-into-object-4.stderr | 2 +- .../regions/regions-proc-bound-capture.stderr | 2 +- .../type-checking-test-4.stderr | 18 ++-- .../dyn-trait-underscore.stderr | 4 +- 14 files changed, 61 insertions(+), 106 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index c7ba5087b8c..3f7aa7773d1 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -139,89 +139,39 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // | ...is captured here... (false, sup_origin.span()) } else { - (true, param.param_ty_span) + (!sup_origin.span().overlaps(return_sp), param.param_ty_span) }; err.span_label(capture_point, &format!("this data with {}...", lifetime)); debug!("try_report_static_impl_trait: param_info={:?}", param); + let mut spans = spans.clone(); + + if mention_capture { + spans.push(sup_origin.span()); + } + spans.sort(); + spans.dedup(); + // We try to make the output have fewer overlapping spans if possible. - if (sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span())) - && sup_origin.span() != return_sp - { - // Customize the spans and labels depending on their relative order so - // that split sentences flow correctly. - if sup_origin.span().overlaps(return_sp) && sp == sup_origin.span() { - // Avoid the following: - // - // error: cannot infer an appropriate lifetime - // --> $DIR/must_outlive_least_region_or_bound.rs:18:50 - // | - // LL | fn foo(x: &i32) -> Box { Box::new(x) } - // | ---- ---------^- - // - // and instead show: - // - // error: cannot infer an appropriate lifetime - // --> $DIR/must_outlive_least_region_or_bound.rs:18:50 - // | - // LL | fn foo(x: &i32) -> Box { Box::new(x) } - // | ---- ^ - err.span_label( - sup_origin.span(), - &format!( - "...is captured here, requiring it to live as long as `'static`{}", - if spans.is_empty() { "" } else { "..." }, - ), - ); - } else { - if return_sp < sup_origin.span() && mention_capture { - err.span_label(sup_origin.span(), "...is captured here..."); - err.span_note( - return_sp, - "...and is required to live as long as `'static` here", - ); - } else { - err.span_label( - return_sp, - &format!( - "...is required to live as long as `'static` here{}", - if spans.is_empty() { "" } else { "..." }, - ), - ); - if mention_capture { - let span = sup_origin.span(); - let msg = if spans.iter().any(|sp| *sp > span) { - "...is captured here..." - } else { - "...and is captured here" - }; - err.span_label(span, msg); - } - } - } + let (require_msg, require_span) = if sup_origin.span().overlaps(return_sp) { + ("...is captured and required to live as long as `'static` here", sup_origin.span()) } else { - err.span_label( - return_sp, - &format!( - "...is captured and required to live as long as `'static` here{}", - if spans.is_empty() { "" } else { "..." }, - ), - ); + ("...and is required to live as long as `'static` here", return_sp) + }; + + for span in &spans { + err.span_label(*span, "...is captured here..."); } - for span in spans { - let msg = - format!("...and is captured here{}", if mention_capture { " too" } else { "" }); - if span.overlaps(return_sp) { - err.span_note(*span, &msg); - } else { - err.span_label(*span, &msg); - } + if spans.iter().any(|sp| sp.overlaps(return_sp) || *sp > return_sp) { + err.span_note(require_span, require_msg); + } else { + err.span_label(require_span, require_msg); } if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin { - err.span_note(*bound, "`'static` lifetime requirement introduced by this trait bound"); + err.span_note(*bound, "`'static` lifetime requirement introduced by this bound"); } let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr index 0be9b37263a..6f63a2c5fc3 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr @@ -4,7 +4,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 { | ------- this data with lifetime `'a`... LL | bar(foo, x) - | ----^^^---- ...is captured and required to live as long as `'static` here + | ^^^ - ...is captured and required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index 0a44864b249..eb81da7852d 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -5,7 +5,7 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> { | -------- this data with lifetime `'a`... ... LL | bar(foo, x) - | ----^^^---- ...is captured and required to live as long as `'static` here + | ^^^ - ...is captured and required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index bb329a4a0c2..7aea147c6cf 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -4,14 +4,14 @@ error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `' LL | pub async fn run_dummy_fn(&self) { | ^^^^^ this data with an anonymous lifetime `'_`... LL | foo(|| self.bar()).await; - | --- ...is required to live as long as `'static` here... + | ------------------------ ...is captured here... | -note: ...and is captured here +note: ...and is required to live as long as `'static` here --> $DIR/issue-62097.rs:13:9 | LL | foo(|| self.bar()).await; - | ^^^^^^^^^^^^^^^^^^^^^^^^ -note: `'static` lifetime requirement introduced by this trait bound + | ^^^ +note: `'static` lifetime requirement introduced by this bound --> $DIR/issue-62097.rs:4:19 | LL | F: FnOnce() + 'static diff --git a/src/test/ui/async-await/issues/issue-72312.rs b/src/test/ui/async-await/issues/issue-72312.rs index d33685e02f1..eb0cc7e6aec 100644 --- a/src/test/ui/async-await/issues/issue-72312.rs +++ b/src/test/ui/async-await/issues/issue-72312.rs @@ -1,6 +1,6 @@ // edition:2018 fn require_static(val: T) -> T { - //~^ NOTE 'static` lifetime requirement introduced by this trait bound + //~^ NOTE 'static` lifetime requirement introduced by this bound val } @@ -10,8 +10,8 @@ impl Problem { pub async fn start(&self) { //~ ERROR E0759 //~^ NOTE this data with an anonymous lifetime `'_` //~| NOTE in this expansion of desugaring of `async` block or function - require_static(async move { //~ NOTE ...is required to live as long as `'static` here - &self; //~ NOTE ...and is captured here + require_static(async move { //~ NOTE ...and is required to live as long as `'static` here + &self; //~ NOTE ...is captured here... }); } } diff --git a/src/test/ui/async-await/issues/issue-72312.stderr b/src/test/ui/async-await/issues/issue-72312.stderr index ee5ee6f0f93..7a72edd4e53 100644 --- a/src/test/ui/async-await/issues/issue-72312.stderr +++ b/src/test/ui/async-await/issues/issue-72312.stderr @@ -4,12 +4,15 @@ error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `' LL | pub async fn start(&self) { | ^^^^^ this data with an anonymous lifetime `'_`... ... -LL | require_static(async move { - | -------------- ...is required to live as long as `'static` here... LL | &self; - | ----- ...and is captured here + | ----- ...is captured here... | -note: `'static` lifetime requirement introduced by this trait bound +note: ...and is required to live as long as `'static` here + --> $DIR/issue-72312.rs:13:9 + | +LL | require_static(async move { + | ^^^^^^^^^^^^^^ +note: `'static` lifetime requirement introduced by this bound --> $DIR/issue-72312.rs:2:22 | LL | fn require_static(val: T) -> T { diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index d65dea7adc9..e80372766dc 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -80,7 +80,7 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:24:65 | LL | fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } - | ---- this data with an anonymous lifetime `'_`... ^ ...is captured here, requiring it to live as long as `'static` + | ---- this data with an anonymous lifetime `'_`... ^ ...is captured and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound | @@ -136,7 +136,7 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:16:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here, requiring it to live as long as `'static` + | ---- ^ ...is captured and required to live as long as `'static` here | | | this data with an anonymous lifetime `'_`... | @@ -149,7 +149,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ^ ...is captured here, requiring it to live as long as `'static` + | ------- ^ ...is captured and required to live as long as `'static` here | | | this data with lifetime `'a`... | @@ -162,7 +162,7 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:20:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured here, requiring it to live as long as `'static` + | ---- ^ ...is captured and required to live as long as `'static` here | | | this data with an anonymous lifetime `'_`... | @@ -179,7 +179,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:22:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- this data with lifetime `'a`... ^ ...is captured here, requiring it to live as long as `'static` + | ------- this data with lifetime `'a`... ^ ...is captured and required to live as long as `'static` here | help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index 8b09b7d5907..ff7b3b67140 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -4,7 +4,7 @@ error[E0759]: `value` has an anonymous lifetime `'_` but it needs to satisfy a ` LL | fn foo(value: &T) -> Box { | -- this data with an anonymous lifetime `'_`... LL | Box::new(value) as Box - | ^^^^^ ...is captured here, requiring it to live as long as `'static` + | ^^^^^ ...is captured and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound | diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 04d22e58a1d..9eb24c1bd37 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -4,7 +4,7 @@ error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn a(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ^ ...is captured here, requiring it to live as long as `'static` + | ^ ...is captured and required to live as long as `'static` here | help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | @@ -21,7 +21,7 @@ error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn b(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... LL | Box::new(v) - | ^ ...is captured here, requiring it to live as long as `'static` + | ^ ...is captured and required to live as long as `'static` here | help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | @@ -39,7 +39,7 @@ LL | fn c(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... ... LL | Box::new(v) - | ^ ...is captured here, requiring it to live as long as `'static` + | ^ ...is captured and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound | diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 9a7df8c0188..9c803d4e1d4 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,7 +4,7 @@ error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | Box::new(B(&*v)) as Box - | ^^^ ...is captured here, requiring it to live as long as `'static` + | ^^^ ...is captured and required to live as long as `'static` here | help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index a7a9b16b080..27bb19a89df 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,7 +4,7 @@ error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | Box::new(B(&*v)) as Box - | ^^^ ...is captured here, requiring it to live as long as `'static` + | ^^^ ...is captured and required to live as long as `'static` here | help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index 50b3748bf40..a257576e5d1 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -5,7 +5,7 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { | ------ this data with an anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^ ...is captured here, requiring it to live as long as `'static` + | ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here | help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr index 04560ea4e29..3d6308a0825 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -39,13 +39,13 @@ LL | let y = x as &dyn Bar<'_, '_>; | ...is captured here... LL | LL | y.get_b() // ERROR - | --------- ...is required to live as long as `'static` here... + | - ...is captured here... | -note: ...and is captured here too +note: ...and is required to live as long as `'static` here --> $DIR/type-checking-test-4.rs:29:5 | LL | y.get_b() // ERROR - | ^ + | ^^^^^^^^^ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement --> $DIR/type-checking-test-4.rs:33:5 @@ -53,7 +53,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | ------------ this data with lifetime `'a`... LL | <_ as Bar>::get_b(x) // ERROR - | ^^^^^^^^^^^^^^^^^ ...is captured here, requiring it to live as long as `'static` + | ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement --> $DIR/type-checking-test-4.rs:38:15 @@ -61,7 +61,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | ------------ this data with lifetime `'a`... LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR - | ----------^^---------------- ...is captured and required to live as long as `'static` here + | ----------^^------------- ...is captured and required to live as long as `'static` here error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement --> $DIR/type-checking-test-4.rs:43:27 @@ -74,16 +74,16 @@ LL | let y = x as &dyn Bar<'_, '_>; | ...is captured here... LL | LL | y.get_b(); // ERROR - | - ...and is captured here too + | - ...is captured here... LL | let z = y; LL | z.get_b() // ERROR - | --------- ...is required to live as long as `'static` here... + | - ...is captured here... | -note: ...and is captured here too +note: ...and is required to live as long as `'static` here --> $DIR/type-checking-test-4.rs:47:5 | LL | z.get_b() // ERROR - | ^ + | ^^^^^^^^^ error: aborting due to 6 previous errors diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index de3a6bbae17..da0f6d0ecde 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -5,7 +5,9 @@ LL | fn a(items: &[T]) -> Box> { | ---- this data with an anonymous lifetime `'_`... LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) - | ---------------^^^^--- ...is captured and required to live as long as `'static` here + | ----- ^^^^ + | | + | ...is captured and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound | From ab45ab83ac0c9b19b6d692ca5d2e9b7b98c3565a Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 12 Oct 2021 08:56:24 +0000 Subject: [PATCH 03/14] review comments * take diagnostic logic out of happy-path * sort/dedup once * add more comments --- .../nice_region_error/static_impl_trait.rs | 10 ++++- .../src/infer/lexical_region_resolve/mod.rs | 40 ++++++++++--------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 3f7aa7773d1..e1f2ec44431 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -150,8 +150,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if mention_capture { spans.push(sup_origin.span()); } - spans.sort(); - spans.dedup(); + // We sort the spans *ignoring* expansion context. Below, the closure logic is repeated + // because one method expects a closure taking `&Span` and the other `&mut Span`. + spans.sort_by_key(|span| (span.lo(), span.hi())); + spans.dedup_by_key(|span| (span.lo(), span.hi())); // We try to make the output have fewer overlapping spans if possible. let (require_msg, require_span) = if sup_origin.span().overlaps(return_sp) { @@ -165,8 +167,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } if spans.iter().any(|sp| sp.overlaps(return_sp) || *sp > return_sp) { + // If any of the "captured here" labels appears on the same line or after + // `require_span`, we put it on a note to ensure the text flows by appearing + // always at the end. err.span_note(require_span, require_msg); } else { + // We don't need a note, it's already at the end, it can be shown as a `span_label`. err.span_label(require_span, require_msg); } diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 14f6c72bb1c..3d4e96fa0f2 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -146,8 +146,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { let graph = self.construct_graph(); self.expand_givens(&graph); self.expansion(&mut var_data); - let captures = self.collect_errors(&mut var_data, errors); - self.collect_var_errors(&var_data, &graph, errors, captures); + self.collect_errors(&mut var_data, errors); + self.collect_var_errors(&var_data, &graph, errors); var_data } @@ -445,16 +445,9 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { &self, var_data: &mut LexicalRegionResolutions<'tcx>, errors: &mut Vec>, - ) -> Vec { - let mut captures = vec![]; - + ) { for (constraint, origin) in &self.data.constraints { debug!(?constraint, ?origin); - if let (Constraint::VarSubVar(_, _), SubregionOrigin::DataBorrowed(_, sp)) = - (constraint, origin) - { - captures.push(*sp); - } match *constraint { Constraint::RegSubVar(..) | Constraint::VarSubVar(..) => { // Expansion will ensure that these constraints hold. Ignore. @@ -524,7 +517,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { sub, )); } - captures } /// Go over the variables that were declared to be error variables @@ -534,7 +526,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { var_data: &LexicalRegionResolutions<'tcx>, graph: &RegionGraph<'tcx>, errors: &mut Vec>, - captures: Vec, ) { debug!("collect_var_errors, var_data = {:#?}", var_data.values); @@ -578,12 +569,27 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // if this rule starts to create problems we'll // have to revisit this portion of the code and // think hard about it. =) -- nikomatsakis + + // Obtain the spans for all the capture points for + // richer diagnostics in `static_impl_trait`. + let captures: Vec = self + .data + .constraints + .iter() + .filter_map(|(constraint, origin)| match (constraint, origin) { + (Constraint::VarSubVar(_, _), SubregionOrigin::DataBorrowed(_, sp)) => { + Some(*sp) + } + _ => None, + }) + .collect(); + self.collect_error_for_expanding_node( graph, &mut dup_vec, node_vid, errors, - &captures, + captures, ); } } @@ -638,7 +644,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { dup_vec: &mut IndexVec>, node_idx: RegionVid, errors: &mut Vec>, - captures: &[Span], + captures: Vec, ) { // Errors in expanding nodes result from a lower-bound that is // not contained by an upper-bound. @@ -686,10 +692,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { origin, node_idx, lower_bound.region, upper_bound.region ); - let mut capture_spans: Vec = captures.iter().cloned().collect(); - // Below, one span expects `&Span` and the other `&mut Span`, hence the dupes. - capture_spans.sort_by_key(|span| (span.lo(), span.hi())); - capture_spans.dedup_by_key(|span| (span.lo(), span.hi())); errors.push(RegionResolutionError::SubSupConflict( node_idx, origin, @@ -697,7 +699,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { lower_bound.region, upper_bound.origin.clone(), upper_bound.region, - capture_spans, + captures, )); return; } From 09dbf37213a5462c08e5e62e931aabc2fb3b92e4 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 12 Oct 2021 09:19:14 +0000 Subject: [PATCH 04/14] Add filtering based on involved required lifetime More accurate filtering still needed. --- .../nice_region_error/static_impl_trait.rs | 8 +++-- .../src/infer/lexical_region_resolve/mod.rs | 29 ++++++++++--------- .../ui/async-await/issues/issue-62097.stderr | 7 +---- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index e1f2ec44431..daeb406a839 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -156,11 +156,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { spans.dedup_by_key(|span| (span.lo(), span.hi())); // We try to make the output have fewer overlapping spans if possible. - let (require_msg, require_span) = if sup_origin.span().overlaps(return_sp) { - ("...is captured and required to live as long as `'static` here", sup_origin.span()) + let require_msg = if spans.is_empty() { + "...is captured and required to live as long as `'static` here" } else { - ("...and is required to live as long as `'static` here", return_sp) + "...and is required to live as long as `'static` here" }; + let require_span = + if sup_origin.span().overlaps(return_sp) { sup_origin.span() } else { return_sp }; for span in &spans { err.span_label(*span, "...is captured here..."); diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 3d4e96fa0f2..b6c1e1f5922 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -48,7 +48,7 @@ pub fn resolve<'tcx>( values.values.iter_mut().for_each(|v| match *v { VarValue::Value(ref mut r) => *r = re_erased, - VarValue::ErrorValue => {} + VarValue::ErrorValue(_) => {} }); (values, errors) } @@ -69,7 +69,7 @@ pub struct LexicalRegionResolutions<'tcx> { #[derive(Copy, Clone, Debug)] enum VarValue<'tcx> { Value(Region<'tcx>), - ErrorValue, + ErrorValue(RegionVid), } #[derive(Clone, Debug)] @@ -233,7 +233,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { (None, a_region, b_vid, b_data) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { - VarValue::ErrorValue => continue, + VarValue::ErrorValue(_) => continue, VarValue::Value(a_region) => { let b_data = var_values.value_mut(b_vid); (Some(a_vid), a_region, b_vid, b_data) @@ -250,7 +250,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } if let Some(a_vid) = a_vid { match *b_data { - VarValue::Value(ReStatic) | VarValue::ErrorValue => (), + VarValue::Value(ReStatic) | VarValue::ErrorValue(_) => (), _ => { constraints[a_vid].push((a_vid, b_vid)); constraints[b_vid].push((a_vid, b_vid)); @@ -262,14 +262,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { while let Some(vid) = changes.pop() { constraints[vid].retain(|&(a_vid, b_vid)| { let a_region = match *var_values.value(a_vid) { - VarValue::ErrorValue => return false, + VarValue::ErrorValue(_) => return false, VarValue::Value(a_region) => a_region, }; let b_data = var_values.value_mut(b_vid); if self.expand_node(a_region, b_vid, b_data) { changes.push(b_vid); } - !matches!(b_data, VarValue::Value(ReStatic) | VarValue::ErrorValue) + !matches!(b_data, VarValue::Value(ReStatic) | VarValue::ErrorValue(_)) }); } } @@ -332,7 +332,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { true } - VarValue::ErrorValue => false, + VarValue::ErrorValue(_) => false, } } @@ -476,7 +476,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { debug!("contraction: {:?} == {:?}, {:?}", a_vid, a_data, b_region); let a_region = match *a_data { - VarValue::ErrorValue => continue, + VarValue::ErrorValue(_) => continue, VarValue::Value(a_region) => a_region, }; @@ -489,7 +489,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { cannot verify that {:?}={:?} <= {:?}", origin, a_vid, a_region, b_region ); - *a_data = VarValue::ErrorValue; + *a_data = VarValue::ErrorValue(a_vid); } } } @@ -545,7 +545,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { for (node_vid, value) in var_data.values.iter_enumerated() { match *value { VarValue::Value(_) => { /* Inference successful */ } - VarValue::ErrorValue => { + VarValue::ErrorValue(reg) => { // Inference impossible: this value contains // inconsistent constraints. // @@ -577,9 +577,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { .constraints .iter() .filter_map(|(constraint, origin)| match (constraint, origin) { - (Constraint::VarSubVar(_, _), SubregionOrigin::DataBorrowed(_, sp)) => { - Some(*sp) - } + ( + Constraint::VarSubVar(_, sup), + SubregionOrigin::DataBorrowed(_, sp), + ) if sup == ® => Some(*sp), _ => None, }) .collect(); @@ -898,7 +899,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> { let result = match self.values[rid] { VarValue::Value(r) => r, - VarValue::ErrorValue => self.error_region, + VarValue::ErrorValue(_) => self.error_region, }; debug!("resolve_var({:?}) = {:?}", rid, result); result diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index 7aea147c6cf..11fb7c86c3b 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -4,13 +4,8 @@ error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `' LL | pub async fn run_dummy_fn(&self) { | ^^^^^ this data with an anonymous lifetime `'_`... LL | foo(|| self.bar()).await; - | ------------------------ ...is captured here... + | --- ...is captured and required to live as long as `'static` here | -note: ...and is required to live as long as `'static` here - --> $DIR/issue-62097.rs:13:9 - | -LL | foo(|| self.bar()).await; - | ^^^ note: `'static` lifetime requirement introduced by this bound --> $DIR/issue-62097.rs:4:19 | From ee0fd105d86f4998a341b9a819735f1087423492 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 12 Oct 2021 09:52:32 +0000 Subject: [PATCH 05/14] Point at return type when it introduces `'static` obligation --- .../nice_region_error/static_impl_trait.rs | 20 ++++++++++++ .../project-fn-ret-invariant.transmute.stderr | 9 ++++++ .../must_outlive_least_region_or_bound.stderr | 28 ++++++++++++++++ ...ect-lifetime-default-from-box-error.stderr | 8 +++++ .../region-object-lifetime-in-coercion.stderr | 15 +++++++++ .../regions-close-object-into-object-2.stderr | 7 ++++ .../regions-close-object-into-object-4.stderr | 7 ++++ .../regions/regions-proc-bound-capture.stderr | 8 +++++ .../type-checking-test-4.stderr | 32 +++++++++++++++++++ .../dyn-trait-underscore.stderr | 8 +++++ 10 files changed, 142 insertions(+) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index daeb406a839..34015b97e3c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -181,6 +181,26 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if let SubregionOrigin::RelateParamBound(_, _, Some(bound)) = sub_origin { err.span_note(*bound, "`'static` lifetime requirement introduced by this bound"); } + if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin { + if let ObligationCauseCode::BlockTailExpression(hir_id) = &cause.code { + let parent_id = tcx.hir().get_parent_item(*hir_id); + if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id) { + let mut span: MultiSpan = fn_decl.output.span().into(); + span.push_span_label( + fn_decl.output.span(), + "requirement introduced by this return type".to_string(), + ); + span.push_span_label( + cause.span, + "because of this returned expression".to_string(), + ); + err.span_note( + span, + "`'static` lifetime requirement introduced by the return type", + ); + } + } + } let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index eb81da7852d..49264ae2505 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -6,6 +6,15 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> { ... LL | bar(foo, x) | ^^^ - ...is captured and required to live as long as `'static` here + | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/project-fn-ret-invariant.rs:45:32 + | +LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> { + | ^^^^^^^^^^^^^ requirement introduced by this return type +... +LL | bar(foo, x) + | ----------- because of this returned expression error: aborting due to previous error diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index e80372766dc..d0d9ed8923d 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -140,6 +140,13 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) } | | | this data with an anonymous lifetime `'_`... | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/must_outlive_least_region_or_bound.rs:14:24 + | +LL | fn elided3(x: &i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^^^^ ----------- because of this returned expression + | | + | requirement introduced by this return type help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound | LL | fn elided3(x: &i32) -> Box { Box::new(x) } @@ -153,6 +160,13 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | | | this data with lifetime `'a`... | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/must_outlive_least_region_or_bound.rs:16:33 + | +LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^^^^ ----------- because of this returned expression + | | + | requirement introduced by this return type help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -166,6 +180,13 @@ LL | fn elided4(x: &i32) -> Box { Box::new(x) } | | | this data with an anonymous lifetime `'_`... | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/must_outlive_least_region_or_bound.rs:18:24 + | +LL | fn elided4(x: &i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- because of this returned expression + | | + | requirement introduced by this return type help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } @@ -181,6 +202,13 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ------- this data with lifetime `'a`... ^ ...is captured and required to live as long as `'static` here | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/must_outlive_least_region_or_bound.rs:20:33 + | +LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } + | ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- because of this returned expression + | | + | requirement introduced by this return type help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index e0a8534cd28..c882e3c9d06 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -7,6 +7,14 @@ LL | fn load(ss: &mut SomeStruct) -> Box { LL | ss.r | ^^^^ ...is captured and required to live as long as `'static` here | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/object-lifetime-default-from-box-error.rs:14:33 + | +LL | fn load(ss: &mut SomeStruct) -> Box { + | ^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +... +LL | ss.r + | ---- because of this returned expression help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound | LL | fn load(ss: &mut SomeStruct) -> Box { diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 9eb24c1bd37..45a3c801a38 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -23,6 +23,13 @@ LL | fn b(v: &[u8]) -> Box { LL | Box::new(v) | ^ ...is captured and required to live as long as `'static` here | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/region-object-lifetime-in-coercion.rs:12:19 + | +LL | fn b(v: &[u8]) -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +LL | Box::new(v) + | ----------- because of this returned expression help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn b(v: &[u8]) -> Box { @@ -41,6 +48,14 @@ LL | fn c(v: &[u8]) -> Box { LL | Box::new(v) | ^ ...is captured and required to live as long as `'static` here | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/region-object-lifetime-in-coercion.rs:16:19 + | +LL | fn c(v: &[u8]) -> Box { + | ^^^^^^^^^^^^ requirement introduced by this return type +... +LL | Box::new(v) + | ----------- because of this returned expression help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound | LL | fn c(v: &[u8]) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index 9c803d4e1d4..a924fbc5bf7 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -6,6 +6,13 @@ LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { LL | Box::new(B(&*v)) as Box | ^^^ ...is captured and required to live as long as `'static` here | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/regions-close-object-into-object-2.rs:8:48 + | +LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { + | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +LL | Box::new(B(&*v)) as Box + | ------------------------------ because of this returned expression help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 27bb19a89df..969222068ee 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -6,6 +6,13 @@ LL | fn i<'a, T, U>(v: Box+'a>) -> Box { LL | Box::new(B(&*v)) as Box | ^^^ ...is captured and required to live as long as `'static` here | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/regions-close-object-into-object-4.rs:8:40 + | +LL | fn i<'a, T, U>(v: Box+'a>) -> Box { + | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +LL | Box::new(B(&*v)) as Box + | ------------------------------ because of this returned expression help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index a257576e5d1..3bbbf00d5e7 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -7,6 +7,14 @@ LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) | ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/regions-proc-bound-capture.rs:7:30 + | +LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +LL | // This is illegal, because the region bound on `proc` is 'static. +LL | Box::new(move || { *x }) + | ------------------------ because of this returned expression help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn static_proc(x: &isize) -> Box (isize) + '_> { diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr index 3d6308a0825..c06943c0874 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -46,6 +46,14 @@ note: ...and is required to live as long as `'static` here | LL | y.get_b() // ERROR | ^^^^^^^^^ +note: `'static` lifetime requirement introduced by the return type + --> $DIR/type-checking-test-4.rs:26:40 + | +LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +... +LL | y.get_b() // ERROR + | --------- because of this returned expression error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement --> $DIR/type-checking-test-4.rs:33:5 @@ -54,6 +62,14 @@ LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | ------------ this data with lifetime `'a`... LL | <_ as Bar>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here + | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/type-checking-test-4.rs:32:40 + | +LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +LL | <_ as Bar>::get_b(x) // ERROR + | -------------------- because of this returned expression error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement --> $DIR/type-checking-test-4.rs:38:15 @@ -62,6 +78,14 @@ LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | ------------ this data with lifetime `'a`... LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR | ----------^^------------- ...is captured and required to live as long as `'static` here + | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/type-checking-test-4.rs:37:40 + | +LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR + | ---------------------------- because of this returned expression error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement --> $DIR/type-checking-test-4.rs:43:27 @@ -84,6 +108,14 @@ note: ...and is required to live as long as `'static` here | LL | z.get_b() // ERROR | ^^^^^^^^^ +note: `'static` lifetime requirement introduced by the return type + --> $DIR/type-checking-test-4.rs:42:40 + | +LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { + | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +... +LL | z.get_b() // ERROR + | --------- because of this returned expression error: aborting due to 6 previous errors diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index da0f6d0ecde..3fed7ba6c49 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -9,6 +9,14 @@ LL | Box::new(items.iter()) | | | ...is captured and required to live as long as `'static` here | +note: `'static` lifetime requirement introduced by the return type + --> $DIR/dyn-trait-underscore.rs:6:25 + | +LL | fn a(items: &[T]) -> Box> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type +LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` +LL | Box::new(items.iter()) + | ---------------------- because of this returned expression help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound | LL | fn a(items: &[T]) -> Box + '_> { From 10a74ac2e0f57f3aaf67991bf4c5be994f240236 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 12 Oct 2021 13:14:11 +0000 Subject: [PATCH 06/14] Use a more accurate `Span` for `'static` obligation from return type --- .../nice_region_error/static_impl_trait.rs | 28 ++++++++++++--- compiler/rustc_middle/src/ty/context.rs | 36 ++----------------- compiler/rustc_middle/src/ty/diagnostics.rs | 20 +++++++++++ .../project-fn-ret-invariant.transmute.stderr | 4 +-- .../must_outlive_least_region_or_bound.stderr | 32 ++++++++--------- ...ect-lifetime-default-from-box-error.stderr | 4 +-- .../region-object-lifetime-in-coercion.stderr | 8 ++--- .../regions-close-object-into-object-2.stderr | 4 +-- .../regions-close-object-into-object-4.stderr | 4 +-- .../regions/regions-proc-bound-capture.stderr | 4 +-- .../type-checking-test-4.stderr | 16 ++++----- .../dyn-trait-underscore.stderr | 4 +-- 12 files changed, 85 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 34015b97e3c..80bdccd4f2c 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -10,7 +10,8 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{walk_ty, ErasedMap, NestedVisitorMap, Visitor}; use rustc_hir::{self as hir, GenericBound, Item, ItemKind, Lifetime, LifetimeName, Node, TyKind}; use rustc_middle::ty::{ - self, AssocItemContainer, RegionKind, Ty, TyCtxt, TypeFoldable, TypeVisitor, + self, AssocItemContainer, RegionKind, StaticLifetimeVisitor, Ty, TyCtxt, TypeFoldable, + TypeVisitor, }; use rustc_span::symbol::Ident; use rustc_span::{MultiSpan, Span}; @@ -186,10 +187,27 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { let parent_id = tcx.hir().get_parent_item(*hir_id); if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id) { let mut span: MultiSpan = fn_decl.output.span().into(); - span.push_span_label( - fn_decl.output.span(), - "requirement introduced by this return type".to_string(), - ); + let mut add_label = true; + if let hir::FnRetTy::Return(ty) = fn_decl.output { + let mut v = StaticLifetimeVisitor(vec![], tcx.hir()); + v.visit_ty(ty); + if !v.0.is_empty() { + span = v.0.clone().into(); + for sp in v.0 { + span.push_span_label( + sp, + "`'static` requirement introduced here".to_string(), + ); + } + add_label = false; + } + } + if add_label { + span.push_span_label( + fn_decl.output.span(), + "requirement introduced by this return type".to_string(), + ); + } span.push_span_label( cause.span, "because of this returned expression".to_string(), diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 275a2128c45..0bf457ca8a8 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1481,40 +1481,8 @@ impl<'tcx> TyCtxt<'tcx> { scope_def_id: LocalDefId, ) -> Vec<&'tcx hir::Ty<'tcx>> { let hir_id = self.hir().local_def_id_to_hir_id(scope_def_id); - let hir_output = match self.hir().get(hir_id) { - Node::Item(hir::Item { - kind: - ItemKind::Fn( - hir::FnSig { - decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. }, - .. - }, - .., - ), - .. - }) - | Node::ImplItem(hir::ImplItem { - kind: - hir::ImplItemKind::Fn( - hir::FnSig { - decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. }, - .. - }, - _, - ), - .. - }) - | Node::TraitItem(hir::TraitItem { - kind: - hir::TraitItemKind::Fn( - hir::FnSig { - decl: hir::FnDecl { output: hir::FnRetTy::Return(ty), .. }, - .. - }, - _, - ), - .. - }) => ty, + let hir_output = match self.hir().fn_decl_by_hir_id(hir_id) { + Some(hir::FnDecl { output: hir::FnRetTy::Return(ty), .. }) => ty, _ => return vec![], }; diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 8803370251b..1acb3ec57de 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -6,6 +6,7 @@ use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::{QPath, TyKind, WhereBoundPredicate, WherePredicate}; +use rustc_span::Span; impl<'tcx> TyS<'tcx> { /// Similar to `TyS::is_primitive`, but also considers inferred numeric values to be primitive. @@ -432,3 +433,22 @@ impl<'v> hir::intravisit::Visitor<'v> for TraitObjectVisitor<'v> { hir::intravisit::walk_ty(self, ty); } } + +/// Collect al types that have an implicit `'static` obligation that we could suggest `'_` for. +pub struct StaticLifetimeVisitor<'tcx>(pub Vec, pub crate::hir::map::Map<'tcx>); + +impl<'v> hir::intravisit::Visitor<'v> for StaticLifetimeVisitor<'v> { + type Map = rustc_hir::intravisit::ErasedMap<'v>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_lifetime(&mut self, lt: &'v hir::Lifetime) { + if let hir::LifetimeName::ImplicitObjectLifetimeDefault | hir::LifetimeName::Static = + lt.name + { + self.0.push(lt.span); + } + } +} diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index 49264ae2505..628023ad471 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -8,10 +8,10 @@ LL | bar(foo, x) | ^^^ - ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/project-fn-ret-invariant.rs:45:32 + --> $DIR/project-fn-ret-invariant.rs:45:37 | LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> { - | ^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here ... LL | bar(foo, x) | ----------- because of this returned expression diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index d0d9ed8923d..bf1f93aebd5 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -141,12 +141,12 @@ LL | fn elided3(x: &i32) -> Box { Box::new(x) } | this data with an anonymous lifetime `'_`... | note: `'static` lifetime requirement introduced by the return type - --> $DIR/must_outlive_least_region_or_bound.rs:14:24 + --> $DIR/must_outlive_least_region_or_bound.rs:14:28 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^^^^ ----------- because of this returned expression - | | - | requirement introduced by this return type + | ^^^^^^^^^ ----------- because of this returned expression + | | + | `'static` requirement introduced here help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound | LL | fn elided3(x: &i32) -> Box { Box::new(x) } @@ -161,12 +161,12 @@ LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | this data with lifetime `'a`... | note: `'static` lifetime requirement introduced by the return type - --> $DIR/must_outlive_least_region_or_bound.rs:16:33 + --> $DIR/must_outlive_least_region_or_bound.rs:16:37 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^^^^ ----------- because of this returned expression - | | - | requirement introduced by this return type + | ^^^^^^^^^ ----------- because of this returned expression + | | + | `'static` requirement introduced here help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } @@ -181,12 +181,12 @@ LL | fn elided4(x: &i32) -> Box { Box::new(x) } | this data with an anonymous lifetime `'_`... | note: `'static` lifetime requirement introduced by the return type - --> $DIR/must_outlive_least_region_or_bound.rs:18:24 + --> $DIR/must_outlive_least_region_or_bound.rs:18:40 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- because of this returned expression - | | - | requirement introduced by this return type + | ^^^^^^^ ----------- because of this returned expression + | | + | `'static` requirement introduced here help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn elided4(x: &i32) -> Box { Box::new(x) } @@ -203,12 +203,12 @@ LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ------- this data with lifetime `'a`... ^ ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/must_outlive_least_region_or_bound.rs:20:33 + --> $DIR/must_outlive_least_region_or_bound.rs:20:49 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ^^^^^^^^^^^^^^^^^^^^^^^^ ----------- because of this returned expression - | | - | requirement introduced by this return type + | ^^^^^^^ ----------- because of this returned expression + | | + | `'static` requirement introduced here help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index c882e3c9d06..0308ecf8f64 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -8,10 +8,10 @@ LL | ss.r | ^^^^ ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/object-lifetime-default-from-box-error.rs:14:33 + --> $DIR/object-lifetime-default-from-box-error.rs:14:37 | LL | fn load(ss: &mut SomeStruct) -> Box { - | ^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^^^^^^^ `'static` requirement introduced here ... LL | ss.r | ---- because of this returned expression diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 45a3c801a38..74683f1439a 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -24,10 +24,10 @@ LL | Box::new(v) | ^ ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/region-object-lifetime-in-coercion.rs:12:19 + --> $DIR/region-object-lifetime-in-coercion.rs:12:33 | LL | fn b(v: &[u8]) -> Box { - | ^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here LL | Box::new(v) | ----------- because of this returned expression help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` @@ -49,10 +49,10 @@ LL | Box::new(v) | ^ ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/region-object-lifetime-in-coercion.rs:16:19 + --> $DIR/region-object-lifetime-in-coercion.rs:16:23 | LL | fn c(v: &[u8]) -> Box { - | ^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here ... LL | Box::new(v) | ----------- because of this returned expression diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index a924fbc5bf7..c914d91306c 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -7,10 +7,10 @@ LL | Box::new(B(&*v)) as Box | ^^^ ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/regions-close-object-into-object-2.rs:8:48 + --> $DIR/regions-close-object-into-object-2.rs:8:60 | LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { - | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here LL | Box::new(B(&*v)) as Box | ------------------------------ because of this returned expression help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 969222068ee..1f68db023a9 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -7,10 +7,10 @@ LL | Box::new(B(&*v)) as Box | ^^^ ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/regions-close-object-into-object-4.rs:8:40 + --> $DIR/regions-close-object-into-object-4.rs:8:52 | LL | fn i<'a, T, U>(v: Box+'a>) -> Box { - | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here LL | Box::new(B(&*v)) as Box | ------------------------------ because of this returned expression help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index 3bbbf00d5e7..99657632035 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -8,10 +8,10 @@ LL | Box::new(move || { *x }) | ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/regions-proc-bound-capture.rs:7:30 + --> $DIR/regions-proc-bound-capture.rs:7:59 | LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) | ------------------------ because of this returned expression diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr index c06943c0874..42230ddd695 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -47,10 +47,10 @@ note: ...and is required to live as long as `'static` here LL | y.get_b() // ERROR | ^^^^^^^^^ note: `'static` lifetime requirement introduced by the return type - --> $DIR/type-checking-test-4.rs:26:40 + --> $DIR/type-checking-test-4.rs:26:48 | LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { - | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here ... LL | y.get_b() // ERROR | --------- because of this returned expression @@ -64,10 +64,10 @@ LL | <_ as Bar>::get_b(x) // ERROR | ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/type-checking-test-4.rs:32:40 + --> $DIR/type-checking-test-4.rs:32:48 | LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { - | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here LL | <_ as Bar>::get_b(x) // ERROR | -------------------- because of this returned expression @@ -80,10 +80,10 @@ LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR | ----------^^------------- ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/type-checking-test-4.rs:37:40 + --> $DIR/type-checking-test-4.rs:37:48 | LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { - | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR | ---------------------------- because of this returned expression @@ -109,10 +109,10 @@ note: ...and is required to live as long as `'static` here LL | z.get_b() // ERROR | ^^^^^^^^^ note: `'static` lifetime requirement introduced by the return type - --> $DIR/type-checking-test-4.rs:42:40 + --> $DIR/type-checking-test-4.rs:42:48 | LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { - | ^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^ `'static` requirement introduced here ... LL | z.get_b() // ERROR | --------- because of this returned expression diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index 3fed7ba6c49..b8552c872c1 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -10,10 +10,10 @@ LL | Box::new(items.iter()) | ...is captured and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/dyn-trait-underscore.rs:6:25 + --> $DIR/dyn-trait-underscore.rs:6:29 | LL | fn a(items: &[T]) -> Box> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ requirement introduced by this return type + | ^^^^^^^^^^^^^^^^^^^^^ `'static` requirement introduced here LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) | ---------------------- because of this returned expression From 0ee723edb54031afdd6e5f07a6daf19dcc34e665 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 12 Oct 2021 13:16:36 +0000 Subject: [PATCH 07/14] Update nll test --- .../ui/async-await/issues/issue-72312.nll.stderr | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/test/ui/async-await/issues/issue-72312.nll.stderr diff --git a/src/test/ui/async-await/issues/issue-72312.nll.stderr b/src/test/ui/async-await/issues/issue-72312.nll.stderr new file mode 100644 index 00000000000..cf7723ada56 --- /dev/null +++ b/src/test/ui/async-await/issues/issue-72312.nll.stderr @@ -0,0 +1,15 @@ +error[E0521]: borrowed data escapes outside of associated function + --> $DIR/issue-72312.rs:13:24 + | +LL | pub async fn start(&self) { + | ----- `self` is a reference that is only valid in the associated function body +... +LL | require_static(async move { + | ________________________^ +LL | | &self; +LL | | }); + | |_________^ `self` escapes the associated function body here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0521`. From ff13ad710f7332079d4ea494f5b0bced68d41429 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 12 Oct 2021 13:28:02 +0000 Subject: [PATCH 08/14] rebase and update nll test --- src/test/ui/async-await/issues/issue-72312.nll.stderr | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/test/ui/async-await/issues/issue-72312.nll.stderr b/src/test/ui/async-await/issues/issue-72312.nll.stderr index cf7723ada56..068d8c64d68 100644 --- a/src/test/ui/async-await/issues/issue-72312.nll.stderr +++ b/src/test/ui/async-await/issues/issue-72312.nll.stderr @@ -2,13 +2,19 @@ error[E0521]: borrowed data escapes outside of associated function --> $DIR/issue-72312.rs:13:24 | LL | pub async fn start(&self) { - | ----- `self` is a reference that is only valid in the associated function body + | ----- + | | + | `self` is a reference that is only valid in the associated function body + | let's call the lifetime of this reference `'1` ... LL | require_static(async move { | ________________________^ LL | | &self; LL | | }); - | |_________^ `self` escapes the associated function body here + | | ^ + | | | + | |_________`self` escapes the associated function body here + | argument requires that `'1` must outlive `'static` error: aborting due to previous error From 83ce1aad428d79ac455fa43b40e0e01b07fcf7cf Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 15 Oct 2021 15:13:21 +0000 Subject: [PATCH 09/14] Tweak wording --- .../nice_region_error/static_impl_trait.rs | 6 ++--- ...ject-fn-ret-contravariant.transmute.stderr | 2 +- .../project-fn-ret-invariant.transmute.stderr | 2 +- .../ui/async-await/issues/issue-62097.stderr | 2 +- src/test/ui/async-await/issues/issue-72312.rs | 2 +- .../ui/async-await/issues/issue-72312.stderr | 2 +- .../dyn-trait.stderr | 2 +- .../must_outlive_least_region_or_bound.stderr | 24 +++++++++---------- src/test/ui/issues/issue-16922.stderr | 2 +- .../constant-in-expr-inherent-1.stderr | 2 +- ...ect-lifetime-default-from-box-error.stderr | 2 +- .../region-object-lifetime-in-coercion.stderr | 6 ++--- .../ui/regions/regions-addr-of-self.stderr | 2 +- .../regions-close-object-into-object-2.stderr | 2 +- .../regions-close-object-into-object-4.stderr | 2 +- .../regions/regions-proc-bound-capture.stderr | 2 +- ...atic-bound-needing-more-suggestions.stderr | 2 +- ...yn-trait-with-implicit-static-bound.stderr | 12 +++++----- .../trait-object-nested-in-impl-trait.stderr | 8 +++---- .../type-checking-test-4.stderr | 14 +++++------ .../dyn-trait-underscore.stderr | 2 +- 21 files changed, 50 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 80bdccd4f2c..1176f131107 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -76,7 +76,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_label( cause.span, &format!( - "...is captured and required to live as long as `'static` here \ + "...is used and required to live as long as `'static` here \ because of an implicit lifetime bound on the {}", match ctxt.assoc_item.container { AssocItemContainer::TraitContainer(id) => @@ -158,7 +158,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { // We try to make the output have fewer overlapping spans if possible. let require_msg = if spans.is_empty() { - "...is captured and required to live as long as `'static` here" + "...is used and required to live as long as `'static` here" } else { "...and is required to live as long as `'static` here" }; @@ -166,7 +166,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if sup_origin.span().overlaps(return_sp) { sup_origin.span() } else { return_sp }; for span in &spans { - err.span_label(*span, "...is captured here..."); + err.span_label(*span, "...is used here..."); } if spans.iter().any(|sp| sp.overlaps(return_sp) || *sp > return_sp) { diff --git a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr index 6f63a2c5fc3..33f1e0f05b2 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-contravariant.transmute.stderr @@ -4,7 +4,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn baz<'a,'b>(x: &'a u32) -> &'static u32 { | ------- this data with lifetime `'a`... LL | bar(foo, x) - | ^^^ - ...is captured and required to live as long as `'static` here + | ^^^ - ...is used and required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr index 628023ad471..609627aaa9e 100644 --- a/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.transmute.stderr @@ -5,7 +5,7 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> { | -------- this data with lifetime `'a`... ... LL | bar(foo, x) - | ^^^ - ...is captured and required to live as long as `'static` here + | ^^^ - ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/project-fn-ret-invariant.rs:45:37 diff --git a/src/test/ui/async-await/issues/issue-62097.stderr b/src/test/ui/async-await/issues/issue-62097.stderr index 11fb7c86c3b..e23277543c6 100644 --- a/src/test/ui/async-await/issues/issue-62097.stderr +++ b/src/test/ui/async-await/issues/issue-62097.stderr @@ -4,7 +4,7 @@ error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `' LL | pub async fn run_dummy_fn(&self) { | ^^^^^ this data with an anonymous lifetime `'_`... LL | foo(|| self.bar()).await; - | --- ...is captured and required to live as long as `'static` here + | --- ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by this bound --> $DIR/issue-62097.rs:4:19 diff --git a/src/test/ui/async-await/issues/issue-72312.rs b/src/test/ui/async-await/issues/issue-72312.rs index eb0cc7e6aec..eb7d12e290c 100644 --- a/src/test/ui/async-await/issues/issue-72312.rs +++ b/src/test/ui/async-await/issues/issue-72312.rs @@ -11,7 +11,7 @@ impl Problem { //~^ NOTE this data with an anonymous lifetime `'_` //~| NOTE in this expansion of desugaring of `async` block or function require_static(async move { //~ NOTE ...and is required to live as long as `'static` here - &self; //~ NOTE ...is captured here... + &self; //~ NOTE ...is used here... }); } } diff --git a/src/test/ui/async-await/issues/issue-72312.stderr b/src/test/ui/async-await/issues/issue-72312.stderr index 7a72edd4e53..798f755765c 100644 --- a/src/test/ui/async-await/issues/issue-72312.stderr +++ b/src/test/ui/async-await/issues/issue-72312.stderr @@ -5,7 +5,7 @@ LL | pub async fn start(&self) { | ^^^^^ this data with an anonymous lifetime `'_`... ... LL | &self; - | ----- ...is captured here... + | ----- ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/issue-72312.rs:13:9 diff --git a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr index b3bef677d19..2307572cc3f 100644 --- a/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr +++ b/src/test/ui/impl-header-lifetime-elision/dyn-trait.stderr @@ -4,7 +4,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn with_dyn_debug_static<'a>(x: Box) { | ------------------- this data with lifetime `'a`... LL | static_val(x); - | ^ ...is captured here... + | ^ ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/dyn-trait.rs:20:5 diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index bf1f93aebd5..de5d3b612c9 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -28,7 +28,7 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:9:46 | LL | fn elided2(x: &i32) -> impl Copy + 'static { x } - | ---- ^ ...is captured here... + | ---- ^ ...is used here... | | | this data with an anonymous lifetime `'_`... | @@ -50,7 +50,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:11:55 | LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } - | ------- ^ ...is captured here... + | ------- ^ ...is used here... | | | this data with lifetime `'a`... | @@ -80,7 +80,7 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:24:65 | LL | fn elided5(x: &i32) -> (Box, impl Debug) { (Box::new(x), x) } - | ---- this data with an anonymous lifetime `'_`... ^ ...is captured and required to live as long as `'static` here + | ---- this data with an anonymous lifetime `'_`... ^ ...is used and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound | @@ -95,7 +95,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:29:69 | LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } - | ------- this data with lifetime `'a`... ^ ...is captured here... + | ------- this data with lifetime `'a`... ^ ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/must_outlive_least_region_or_bound.rs:29:34 @@ -136,12 +136,12 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:16:50 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured and required to live as long as `'static` here + | ---- ^ ...is used and required to live as long as `'static` here | | | this data with an anonymous lifetime `'_`... | note: `'static` lifetime requirement introduced by the return type - --> $DIR/must_outlive_least_region_or_bound.rs:14:28 + --> $DIR/must_outlive_least_region_or_bound.rs:16:28 | LL | fn elided3(x: &i32) -> Box { Box::new(x) } | ^^^^^^^^^ ----------- because of this returned expression @@ -156,12 +156,12 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:18:59 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- ^ ...is captured and required to live as long as `'static` here + | ------- ^ ...is used and required to live as long as `'static` here | | | this data with lifetime `'a`... | note: `'static` lifetime requirement introduced by the return type - --> $DIR/must_outlive_least_region_or_bound.rs:16:37 + --> $DIR/must_outlive_least_region_or_bound.rs:18:37 | LL | fn explicit3<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^^^^^^ ----------- because of this returned expression @@ -176,12 +176,12 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta --> $DIR/must_outlive_least_region_or_bound.rs:20:60 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } - | ---- ^ ...is captured and required to live as long as `'static` here + | ---- ^ ...is used and required to live as long as `'static` here | | | this data with an anonymous lifetime `'_`... | note: `'static` lifetime requirement introduced by the return type - --> $DIR/must_outlive_least_region_or_bound.rs:18:40 + --> $DIR/must_outlive_least_region_or_bound.rs:20:40 | LL | fn elided4(x: &i32) -> Box { Box::new(x) } | ^^^^^^^ ----------- because of this returned expression @@ -200,10 +200,10 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime --> $DIR/must_outlive_least_region_or_bound.rs:22:69 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } - | ------- this data with lifetime `'a`... ^ ...is captured and required to live as long as `'static` here + | ------- this data with lifetime `'a`... ^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/must_outlive_least_region_or_bound.rs:20:49 + --> $DIR/must_outlive_least_region_or_bound.rs:22:49 | LL | fn explicit4<'a>(x: &'a i32) -> Box { Box::new(x) } | ^^^^^^^ ----------- because of this returned expression diff --git a/src/test/ui/issues/issue-16922.stderr b/src/test/ui/issues/issue-16922.stderr index ff7b3b67140..53405a660f8 100644 --- a/src/test/ui/issues/issue-16922.stderr +++ b/src/test/ui/issues/issue-16922.stderr @@ -4,7 +4,7 @@ error[E0759]: `value` has an anonymous lifetime `'_` but it needs to satisfy a ` LL | fn foo(value: &T) -> Box { | -- this data with an anonymous lifetime `'_`... LL | Box::new(value) as Box - | ^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^ ...is used and required to live as long as `'static` here | help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound | diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr index 1931934a211..4a6378b84f1 100644 --- a/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr +++ b/src/test/ui/nll/user-annotations/constant-in-expr-inherent-1.stderr @@ -4,7 +4,7 @@ error[E0759]: `fn` parameter has lifetime `'a` but it needs to satisfy a `'stati LL | fn foo<'a>(_: &'a u32) -> &'static u32 { | ------- this data with lifetime `'a`... LL | >::C - | ^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^^^^^ ...is used and required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr index 0308ecf8f64..1708700f77a 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.stderr @@ -5,7 +5,7 @@ LL | fn load(ss: &mut SomeStruct) -> Box { | --------------- this data with an anonymous lifetime `'_`... ... LL | ss.r - | ^^^^ ...is captured and required to live as long as `'static` here + | ^^^^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/object-lifetime-default-from-box-error.rs:14:37 diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr index 74683f1439a..d8932c067ac 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.stderr @@ -4,7 +4,7 @@ error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn a(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... LL | let x: Box = Box::new(v); - | ^ ...is captured and required to live as long as `'static` here + | ^ ...is used and required to live as long as `'static` here | help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` | @@ -21,7 +21,7 @@ error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn b(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... LL | Box::new(v) - | ^ ...is captured and required to live as long as `'static` here + | ^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/region-object-lifetime-in-coercion.rs:12:33 @@ -46,7 +46,7 @@ LL | fn c(v: &[u8]) -> Box { | ----- this data with an anonymous lifetime `'_`... ... LL | Box::new(v) - | ^ ...is captured and required to live as long as `'static` here + | ^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/region-object-lifetime-in-coercion.rs:16:23 diff --git a/src/test/ui/regions/regions-addr-of-self.stderr b/src/test/ui/regions/regions-addr-of-self.stderr index 738691fd695..3453c6458f1 100644 --- a/src/test/ui/regions/regions-addr-of-self.stderr +++ b/src/test/ui/regions/regions-addr-of-self.stderr @@ -4,7 +4,7 @@ error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `' LL | pub fn chase_cat(&mut self) { | --------- this data with an anonymous lifetime `'_`... LL | let p: &'static mut usize = &mut self.cats_chased; - | ^^^^^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^^^^^^^^^^^^^^ ...is used and required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.stderr index c914d91306c..4153f4f29bc 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.stderr @@ -4,7 +4,7 @@ error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn g<'a, T: 'static>(v: Box + 'a>) -> Box { | ------------------ this data with lifetime `'a`... LL | Box::new(B(&*v)) as Box - | ^^^ ...is captured and required to live as long as `'static` here + | ^^^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/regions-close-object-into-object-2.rs:8:60 diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.stderr index 1f68db023a9..2ea4b431b38 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.stderr @@ -4,7 +4,7 @@ error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn i<'a, T, U>(v: Box+'a>) -> Box { | ---------------- this data with lifetime `'a`... LL | Box::new(B(&*v)) as Box - | ^^^ ...is captured and required to live as long as `'static` here + | ^^^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/regions-close-object-into-object-4.rs:8:52 diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.stderr index 99657632035..2ebe874da93 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.stderr @@ -5,7 +5,7 @@ LL | fn static_proc(x: &isize) -> Box (isize) + 'static> { | ------ this data with an anonymous lifetime `'_`... LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) - | ^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^^^^^^^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/regions-proc-bound-capture.rs:7:59 diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr index 2961d8d7eac..63d291ed7cd 100644 --- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr +++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr @@ -22,7 +22,7 @@ error[E0772]: `val` has lifetime `'a` but calling `use_self` introduces an impli LL | fn use_it<'a>(val: Box + 'a>) -> &'a () { | -------------------------------------- this data with lifetime `'a`... LL | val.use_self() - | ^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^ ...is used and required to live as long as `'static` here | note: the used `impl` has a `'static` requirement --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:60:30 diff --git a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr index 6d9f0811b27..55a1bbf18ab 100644 --- a/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr +++ b/src/test/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr @@ -4,7 +4,7 @@ error[E0759]: `val` has lifetime `'a` but it needs to satisfy a `'static` lifeti LL | fn use_it<'a, T>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { | ---------------------- this data with lifetime `'a`... LL | val.use_self::() - | ^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^ ...is used and required to live as long as `'static` here | note: the used `impl` has a `'static` requirement --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:14:32 @@ -24,7 +24,7 @@ error[E0772]: `val` has lifetime `'a` but calling `use_self` introduces an impli LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { | ------------------- this data with lifetime `'a`... LL | val.use_self() - | ^^^^^^^^ ...is captured and required to live as long as `'static` here because of an implicit lifetime bound on the inherent `impl` + | ^^^^^^^^ ...is used and required to live as long as `'static` here because of an implicit lifetime bound on the inherent `impl` | note: the used `impl` has a `'static` requirement --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:64:14 @@ -44,7 +44,7 @@ error[E0759]: `val` has lifetime `'a` but it needs to satisfy a `'static` lifeti LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> { | ------------------- this data with lifetime `'a`... LL | val.use_self() - | ^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^ ...is used and required to live as long as `'static` here | note: the used `impl` has a `'static` requirement --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:85:26 @@ -69,7 +69,7 @@ error[E0759]: `val` has lifetime `'a` but it needs to satisfy a `'static` lifeti LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a { | ------------------- this data with lifetime `'a`... LL | MyTrait::use_self(val) - | ^^^ ...is captured here... + | ^^^ ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:108:9 @@ -95,7 +95,7 @@ error[E0772]: `val` has lifetime `'a` but calling `use_self` introduces an impli LL | fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () { | ------------------- this data with lifetime `'a`... LL | val.use_self() - | ^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^ ...is used and required to live as long as `'static` here | note: the used `impl` has a `'static` requirement --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:31:26 @@ -115,7 +115,7 @@ error[E0772]: `val` has lifetime `'a` but calling `use_self` introduces an impli LL | fn use_it<'a>(val: &'a Box) -> &'a () { | ----------------------------- this data with lifetime `'a`... LL | val.use_self() - | ^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^ ...is used and required to live as long as `'static` here | note: the used `impl` has a `'static` requirement --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:48:30 diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr index 1ca22ebeef4..a5b50634c71 100644 --- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr +++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr @@ -7,7 +7,7 @@ LL | fn iter(&self) -> impl Iterator> { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is captured here... + | ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:27:23 @@ -32,7 +32,7 @@ LL | fn iter(&self) -> impl Iterator> + '_ { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is captured here... + | ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:38:23 @@ -53,7 +53,7 @@ LL | fn iter<'a>(&'a self) -> impl Iterator> + 'a { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is captured here... + | ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:49:30 @@ -74,7 +74,7 @@ LL | fn iter<'a>(&'a self) -> impl Iterator> { LL | remaining: self.0.iter(), | ------ ^^^^ | | - | ...is captured here... + | ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/trait-object-nested-in-impl-trait.rs:60:30 diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr index 42230ddd695..d4bb9350b0b 100644 --- a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr +++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr @@ -36,10 +36,10 @@ LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { LL | let y = x as &dyn Bar<'_, '_>; | - ^^ | | - | ...is captured here... + | ...is used here... LL | LL | y.get_b() // ERROR - | - ...is captured here... + | - ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/type-checking-test-4.rs:29:5 @@ -61,7 +61,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn test_wrong4<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | ------------ this data with lifetime `'a`... LL | <_ as Bar>::get_b(x) // ERROR - | ^^^^^^^^^^^^^^^^^ ...is captured and required to live as long as `'static` here + | ^^^^^^^^^^^^^^^^^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/type-checking-test-4.rs:32:48 @@ -77,7 +77,7 @@ error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime LL | fn test_wrong5<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { | ------------ this data with lifetime `'a`... LL | <_ as Bar<'_, '_>>::get_b(x) // ERROR - | ----------^^------------- ...is captured and required to live as long as `'static` here + | ----------^^------------- ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/type-checking-test-4.rs:37:48 @@ -95,13 +95,13 @@ LL | fn test_wrong6<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> { LL | let y = x as &dyn Bar<'_, '_>; | - ^^ | | - | ...is captured here... + | ...is used here... LL | LL | y.get_b(); // ERROR - | - ...is captured here... + | - ...is used here... LL | let z = y; LL | z.get_b() // ERROR - | - ...is captured here... + | - ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/type-checking-test-4.rs:47:5 diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr index b8552c872c1..f4285a0f98e 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr @@ -7,7 +7,7 @@ LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to LL | Box::new(items.iter()) | ----- ^^^^ | | - | ...is captured and required to live as long as `'static` here + | ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type --> $DIR/dyn-trait-underscore.rs:6:29 From 9cc7bd769208a9db9670649d6fdede04f1a886fc Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 16 Nov 2021 22:23:41 +0000 Subject: [PATCH 10/14] Review comments --- .../nice_region_error/static_impl_trait.rs | 9 +++++---- .../src/infer/lexical_region_resolve/mod.rs | 13 +++++++------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 1176f131107..dab0b87f7ae 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -151,9 +151,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if mention_capture { spans.push(sup_origin.span()); } - // We sort the spans *ignoring* expansion context. Below, the closure logic is repeated - // because one method expects a closure taking `&Span` and the other `&mut Span`. - spans.sort_by_key(|span| (span.lo(), span.hi())); + // We dedup the spans *ignoring* expansion context. + spans.sort(); spans.dedup_by_key(|span| (span.lo(), span.hi())); // We try to make the output have fewer overlapping spans if possible. @@ -183,7 +182,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { err.span_note(*bound, "`'static` lifetime requirement introduced by this bound"); } if let SubregionOrigin::Subtype(box TypeTrace { cause, .. }) = sub_origin { - if let ObligationCauseCode::BlockTailExpression(hir_id) = &cause.code { + if let ObligationCauseCode::ReturnValue(hir_id) + | ObligationCauseCode::BlockTailExpression(hir_id) = &cause.code + { let parent_id = tcx.hir().get_parent_item(*hir_id); if let Some(fn_decl) = tcx.hir().fn_decl_by_hir_id(parent_id) { let mut span: MultiSpan = fn_decl.output.span().into(); diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index b6c1e1f5922..08a58fa67e0 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -97,7 +97,7 @@ pub enum RegionResolutionError<'tcx> { Region<'tcx>, SubregionOrigin<'tcx>, Region<'tcx>, - Vec, + Vec, // All the influences on a given value that didn't meet its constraints. ), /// Indicates a `'b: 'a` constraint where `'a` is in a universe that @@ -570,9 +570,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // have to revisit this portion of the code and // think hard about it. =) -- nikomatsakis - // Obtain the spans for all the capture points for + // Obtain the spans for all the places that can + // influence the constraints on this value for // richer diagnostics in `static_impl_trait`. - let captures: Vec = self + let influences: Vec = self .data .constraints .iter() @@ -590,7 +591,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { &mut dup_vec, node_vid, errors, - captures, + influences, ); } } @@ -645,7 +646,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { dup_vec: &mut IndexVec>, node_idx: RegionVid, errors: &mut Vec>, - captures: Vec, + influences: Vec, ) { // Errors in expanding nodes result from a lower-bound that is // not contained by an upper-bound. @@ -700,7 +701,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { lower_bound.region, upper_bound.origin.clone(), upper_bound.region, - captures, + influences, )); return; } From d33fa135fe1c03ee51a84f7c6bb03a53eb3e3eed Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Tue, 16 Nov 2021 22:58:54 +0000 Subject: [PATCH 11/14] Remove field from `ErrorValue` --- .../src/infer/lexical_region_resolve/mod.rs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 08a58fa67e0..85ee6d2cdc2 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -48,7 +48,7 @@ pub fn resolve<'tcx>( values.values.iter_mut().for_each(|v| match *v { VarValue::Value(ref mut r) => *r = re_erased, - VarValue::ErrorValue(_) => {} + VarValue::ErrorValue => {} }); (values, errors) } @@ -69,7 +69,7 @@ pub struct LexicalRegionResolutions<'tcx> { #[derive(Copy, Clone, Debug)] enum VarValue<'tcx> { Value(Region<'tcx>), - ErrorValue(RegionVid), + ErrorValue, } #[derive(Clone, Debug)] @@ -233,7 +233,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { (None, a_region, b_vid, b_data) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { - VarValue::ErrorValue(_) => continue, + VarValue::ErrorValue => continue, VarValue::Value(a_region) => { let b_data = var_values.value_mut(b_vid); (Some(a_vid), a_region, b_vid, b_data) @@ -250,7 +250,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } if let Some(a_vid) = a_vid { match *b_data { - VarValue::Value(ReStatic) | VarValue::ErrorValue(_) => (), + VarValue::Value(ReStatic) | VarValue::ErrorValue => (), _ => { constraints[a_vid].push((a_vid, b_vid)); constraints[b_vid].push((a_vid, b_vid)); @@ -262,14 +262,14 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { while let Some(vid) = changes.pop() { constraints[vid].retain(|&(a_vid, b_vid)| { let a_region = match *var_values.value(a_vid) { - VarValue::ErrorValue(_) => return false, + VarValue::ErrorValue => return false, VarValue::Value(a_region) => a_region, }; let b_data = var_values.value_mut(b_vid); if self.expand_node(a_region, b_vid, b_data) { changes.push(b_vid); } - !matches!(b_data, VarValue::Value(ReStatic) | VarValue::ErrorValue(_)) + !matches!(b_data, VarValue::Value(ReStatic) | VarValue::ErrorValue) }); } } @@ -332,7 +332,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { true } - VarValue::ErrorValue(_) => false, + VarValue::ErrorValue => false, } } @@ -476,7 +476,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { debug!("contraction: {:?} == {:?}, {:?}", a_vid, a_data, b_region); let a_region = match *a_data { - VarValue::ErrorValue(_) => continue, + VarValue::ErrorValue => continue, VarValue::Value(a_region) => a_region, }; @@ -489,7 +489,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { cannot verify that {:?}={:?} <= {:?}", origin, a_vid, a_region, b_region ); - *a_data = VarValue::ErrorValue(a_vid); + *a_data = VarValue::ErrorValue; } } } @@ -545,7 +545,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { for (node_vid, value) in var_data.values.iter_enumerated() { match *value { VarValue::Value(_) => { /* Inference successful */ } - VarValue::ErrorValue(reg) => { + VarValue::ErrorValue => { // Inference impossible: this value contains // inconsistent constraints. // @@ -581,7 +581,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ( Constraint::VarSubVar(_, sup), SubregionOrigin::DataBorrowed(_, sp), - ) if sup == ® => Some(*sp), + ) if sup == &node_vid => Some(*sp), _ => None, }) .collect(); @@ -900,7 +900,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { pub fn resolve_var(&self, rid: RegionVid) -> ty::Region<'tcx> { let result = match self.values[rid] { VarValue::Value(r) => r, - VarValue::ErrorValue(_) => self.error_region, + VarValue::ErrorValue => self.error_region, }; debug!("resolve_var({:?}) = {:?}", rid, result); result From da5b0cc851535e1f4af667ab15254b2e8f85f3a3 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 10 Dec 2021 03:18:03 +0000 Subject: [PATCH 12/14] review comment --- .../error_reporting/nice_region_error/static_impl_trait.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index dab0b87f7ae..36d88029252 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -126,7 +126,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { lifetime, ); - let (mention_capture, capture_point) = if sup_origin.span().overlaps(param.param_ty_span) { + let (mention_influencer, influencer_point) = if sup_origin.span().overlaps(param.param_ty_span) { // Account for `async fn` like in `async-await/issues/issue-62097.rs`. // The desugaring of `async `fn`s causes `sup_origin` and `param` to point at the same // place (but with different `ctxt`, hence `overlaps` instead of `==` above). @@ -142,13 +142,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } else { (!sup_origin.span().overlaps(return_sp), param.param_ty_span) }; - err.span_label(capture_point, &format!("this data with {}...", lifetime)); + err.span_label(influencer_point, &format!("this data with {}...", lifetime)); debug!("try_report_static_impl_trait: param_info={:?}", param); let mut spans = spans.clone(); - if mention_capture { + if mention_influencer { spans.push(sup_origin.span()); } // We dedup the spans *ignoring* expansion context. From 40f161aeb0981030d3959acd239cb0bb2e600597 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 10 Dec 2021 03:18:29 +0000 Subject: [PATCH 13/14] fix tests after rebase --- ...losure-bounds-static-cant-capture-borrowed.stderr | 7 ++++++- .../generator/generator-region-requirements.stderr | 2 +- .../projection-type-lifetime-mismatch.stderr | 12 +++++++++--- src/test/ui/issues/issue-46983.stderr | 2 +- ...ssue-90600-expected-return-static-indirect.stderr | 2 +- src/test/ui/regions/regions-static-bound.stderr | 4 ++-- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr index d761abdfc6a..af1f908a808 100644 --- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr +++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.stderr @@ -8,13 +8,18 @@ LL | bar(|| { LL | | LL | | let _ = x; LL | | }) - | |_____^ ...is captured here... + | |_____^ ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5 | LL | bar(|| { | ^^^ +note: `'static` lifetime requirement introduced by this bound + --> $DIR/closure-bounds-static-cant-capture-borrowed.rs:1:39 + | +LL | fn bar(blk: F) where F: FnOnce() + 'static { + | ^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/generator/generator-region-requirements.stderr b/src/test/ui/generator/generator-region-requirements.stderr index b6b9db22426..30d67050b90 100644 --- a/src/test/ui/generator/generator-region-requirements.stderr +++ b/src/test/ui/generator/generator-region-requirements.stderr @@ -5,7 +5,7 @@ LL | fn dangle(x: &mut i32) -> &'static mut i32 { | -------- this data with an anonymous lifetime `'_`... ... LL | x - | ^ ...is captured here... + | ^ ...is used here... ... LL | GeneratorState::Complete(c) => return c, | - ...and is required to live as long as `'static` here diff --git a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr index 1ffd205652f..32c5ccf1648 100644 --- a/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr +++ b/src/test/ui/generic-associated-types/projection-type-lifetime-mismatch.stderr @@ -4,7 +4,9 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn f(x: &impl for<'a> X = &'a ()>) -> &'static () { | ------------------------------- this data with an anonymous lifetime `'_`... LL | x.m() - | --^-- ...is captured and required to live as long as `'static` here + | - ^ + | | + | ...is used and required to live as long as `'static` here error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/projection-type-lifetime-mismatch.rs:22:7 @@ -12,7 +14,9 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn g X = &'a ()>>(x: &T) -> &'static () { | -- this data with an anonymous lifetime `'_`... LL | x.m() - | --^-- ...is captured and required to live as long as `'static` here + | - ^ + | | + | ...is used and required to live as long as `'static` here error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/projection-type-lifetime-mismatch.rs:27:7 @@ -20,7 +24,9 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn h(x: &()) -> &'static () { | --- this data with an anonymous lifetime `'_`... LL | x.m() - | --^-- ...is captured and required to live as long as `'static` here + | - ^ + | | + | ...is used and required to live as long as `'static` here error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-46983.stderr b/src/test/ui/issues/issue-46983.stderr index 77fb130f519..ed9f1884c42 100644 --- a/src/test/ui/issues/issue-46983.stderr +++ b/src/test/ui/issues/issue-46983.stderr @@ -4,7 +4,7 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn foo(x: &u32) -> &'static u32 { | ---- this data with an anonymous lifetime `'_`... LL | &*x - | ^^^ ...is captured and required to live as long as `'static` here + | ^^^ ...is used and required to live as long as `'static` here error: aborting due to previous error diff --git a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr index 3f65d3af725..e06255e4ea3 100644 --- a/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr +++ b/src/test/ui/lifetimes/issue-90600-expected-return-static-indirect.stderr @@ -4,7 +4,7 @@ error[E0759]: `foo` has an anonymous lifetime `'_` but it needs to satisfy a `'s LL | fn inner(mut foo: &[u8]) { | ----- this data with an anonymous lifetime `'_`... LL | let refcell = RefCell::new(&mut foo); - | ^^^^^^^^ ...is captured here... + | ^^^^^^^^ ...is used here... ... LL | read_thing(read); | ---- ...and is required to live as long as `'static` here diff --git a/src/test/ui/regions/regions-static-bound.stderr b/src/test/ui/regions/regions-static-bound.stderr index 51fe16ca9da..b8e69e02609 100644 --- a/src/test/ui/regions/regions-static-bound.stderr +++ b/src/test/ui/regions/regions-static-bound.stderr @@ -17,7 +17,7 @@ error[E0759]: `u` has an anonymous lifetime `'_` but it needs to satisfy a `'sta LL | fn error(u: &(), v: &()) { | --- this data with an anonymous lifetime `'_`... LL | static_id(&u); - | ^^^^^^^^^ -- ...is captured here... + | ^^^^^^^^^ -- ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/regions-static-bound.rs:10:5 @@ -32,7 +32,7 @@ LL | fn error(u: &(), v: &()) { | --- this data with an anonymous lifetime `'_`... LL | static_id(&u); LL | static_id_indirect(&v); - | ^^^^^^^^^^^^^^^^^^ -- ...is captured here... + | ^^^^^^^^^^^^^^^^^^ -- ...is used here... | note: ...and is required to live as long as `'static` here --> $DIR/regions-static-bound.rs:11:5 From d2d9eb3715e61d16eafb55b4b8cb03fdc6bfc871 Mon Sep 17 00:00:00 2001 From: Esteban Kuber Date: Fri, 10 Dec 2021 17:22:33 +0000 Subject: [PATCH 14/14] fmt --- .../nice_region_error/static_impl_trait.rs | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 36d88029252..80d4a2e57da 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -126,22 +126,23 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { lifetime, ); - let (mention_influencer, influencer_point) = if sup_origin.span().overlaps(param.param_ty_span) { - // Account for `async fn` like in `async-await/issues/issue-62097.rs`. - // The desugaring of `async `fn`s causes `sup_origin` and `param` to point at the same - // place (but with different `ctxt`, hence `overlaps` instead of `==` above). - // - // This avoids the following: - // - // LL | pub async fn run_dummy_fn(&self) { - // | ^^^^^ - // | | - // | this data with an anonymous lifetime `'_`... - // | ...is captured here... - (false, sup_origin.span()) - } else { - (!sup_origin.span().overlaps(return_sp), param.param_ty_span) - }; + let (mention_influencer, influencer_point) = + if sup_origin.span().overlaps(param.param_ty_span) { + // Account for `async fn` like in `async-await/issues/issue-62097.rs`. + // The desugaring of `async `fn`s causes `sup_origin` and `param` to point at the same + // place (but with different `ctxt`, hence `overlaps` instead of `==` above). + // + // This avoids the following: + // + // LL | pub async fn run_dummy_fn(&self) { + // | ^^^^^ + // | | + // | this data with an anonymous lifetime `'_`... + // | ...is captured here... + (false, sup_origin.span()) + } else { + (!sup_origin.span().overlaps(return_sp), param.param_ty_span) + }; err.span_label(influencer_point, &format!("this data with {}...", lifetime)); debug!("try_report_static_impl_trait: param_info={:?}", param);