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 |