Skip to content

Commit

Permalink
Tweak wording and spans of 'static dyn Trait/impl Trait require…
Browse files Browse the repository at this point in the history
…ments
  • Loading branch information
estebank committed May 30, 2020
1 parent 6dcd744 commit 83f6f22
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,39 +27,44 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let return_sp = sub_origin.span();
let mut err =
self.tcx().sess.struct_span_err(sp, "cannot infer an appropriate lifetime");
if sp == sup_origin.span() && return_sp == sp {
// Example: `ui/object-lifetime/object-lifetime-default-from-box-error.rs`
err.span_label(
sup_origin.span(),
"this needs to be `'static` but the borrow...",
);
} else {
err.span_label(return_sp, "this is `'static`...");
// We try to make the output have fewer overlapping spans if possible.
if sp == sup_origin.span() || !return_sp.overlaps(sup_origin.span()) {
// When `sp == sup_origin` we already have overlapping spans in the
// main diagnostic output, so we don't split this into its own note.
err.span_label(sup_origin.span(), "...but this borrow...");
let param_info = self.find_param_with_region(sup_r, sub_r)?;
err.span_label(param_info.param_ty_span, "data with this lifetime...");

// 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().shrink_to_hi() <= return_sp.shrink_to_lo() {
err.span_label(sup_origin.span(), "...is captured here...");
err.span_label(return_sp, "...and required to be `'static` by this");
} else {
err.span_note(sup_origin.span(), "...but this borrow...");
err.span_label(return_sp, "...is required to be `'static` by this...");
err.span_label(sup_origin.span(), "...and is captured here");
}
} else {
err.span_label(
return_sp,
"...is captured and required to be `'static` here",
);
}

let (lifetime, lt_sp_opt) = msg_span_from_free_region(self.tcx(), sup_r);
if let Some(lifetime_sp) = lt_sp_opt {
err.span_note(lifetime_sp, &format!("...can't outlive {}", lifetime));
}
let (lifetime, _) = msg_span_from_free_region(self.tcx(), sup_r);

let lifetime_name =
if sup_r.has_name() { sup_r.to_string() } else { "'_".to_owned() };
// only apply this suggestion onto functions with
// explicit non-desugar'able return.
if fn_return_span.desugaring_kind().is_none() {
let msg = format!(
"you can add a bound to the returned `{} Trait` to make it last less \
than `'static` and match {}",
"to permit non-static references in {} `{} Trait` value, you can add \
an explicit bound for {}",
if is_dyn { "a" } else { "an" },
if is_dyn { "dyn" } else { "impl" },
lifetime
lifetime,
);
// FIXME: account for the need of parens in `&(dyn Trait + '_)`
err.span_suggestion_verbose(
Expand Down
13 changes: 5 additions & 8 deletions src/test/ui/async-await/issues/issue-62097.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ error: cannot infer an appropriate lifetime
--> $DIR/issue-62097.rs:12:31
|
LL | pub async fn run_dummy_fn(&self) {
| ^^^^^ ...but this borrow...
| ^^^^^
| |
| data with this lifetime...
| ...is captured here...
LL | foo(|| self.bar()).await;
| --- this is `'static`...
|
note: ...can't outlive the lifetime `'_` as defined on the method body at 12:31
--> $DIR/issue-62097.rs:12:31
|
LL | pub async fn run_dummy_fn(&self) {
| ^
| --- ...and required to be `'static` by this

error: aborting due to previous error

42 changes: 15 additions & 27 deletions src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:3:35
|
LL | fn elided(x: &i32) -> impl Copy { x }
| --------- ^ ...but this borrow...
| |
| this is `'static`...
| ---- --------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
| data with this lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 3:1
--> $DIR/must_outlive_least_region_or_bound.rs:3:1
|
LL | fn elided(x: &i32) -> impl Copy { x }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
|
LL | fn elided(x: &i32) -> impl Copy + '_ { x }
| ^^^^
Expand All @@ -20,16 +16,12 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:6:44
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| --------- ^ ...but this borrow...
| |
| this is `'static`...
|
note: ...can't outlive the lifetime `'a` as defined on the function body at 6:13
--> $DIR/must_outlive_least_region_or_bound.rs:6:13
| ------- --------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
| data with this lifetime...
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x }
| ^^
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 6:13
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 6:13
|
LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x }
| ^^^^
Expand All @@ -38,16 +30,12 @@ error: cannot infer an appropriate lifetime
--> $DIR/must_outlive_least_region_or_bound.rs:12:69
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| -------------------------------- ^ ...but this borrow...
| |
| this is `'static`...
|
note: ...can't outlive the lifetime `'a` as defined on the function body at 12:15
--> $DIR/must_outlive_least_region_or_bound.rs:12:15
| ------- -------------------------------- ^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
| data with this lifetime...
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
| ^^
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the lifetime `'a` as defined on the function body at 12:15
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the function body at 12:15
|
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static + 'a { x }
| ^^^^
Expand Down
28 changes: 10 additions & 18 deletions src/test/ui/impl-trait/static-return-lifetime-infered.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,15 @@ error: cannot infer an appropriate lifetime
--> $DIR/static-return-lifetime-infered.rs:7:16
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
| ----------------------- this is `'static`...
| ----- ----------------------- ...is required to be `'static` by this...
| |
| data with this lifetime...
LL | self.x.iter().map(|a| a.0)
| ------ ^^^^
| |
| ...but this borrow...
| ...and is captured here
|
note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5
--> $DIR/static-return-lifetime-infered.rs:6:5
|
LL | / fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
LL | | self.x.iter().map(|a| a.0)
LL | | }
| |_____^
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5
|
LL | fn iter_values_anon(&self) -> impl Iterator<Item=u32> + '_ {
| ^^^^
Expand All @@ -24,18 +19,15 @@ error: cannot infer an appropriate lifetime
--> $DIR/static-return-lifetime-infered.rs:11:16
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| ----------------------- this is `'static`...
| -------- ----------------------- ...is required to be `'static` by this...
| |
| data with this lifetime...
LL | self.x.iter().map(|a| a.0)
| ------ ^^^^
| |
| ...but this borrow...
|
note: ...can't outlive the lifetime `'a` as defined on the method body at 10:20
--> $DIR/static-return-lifetime-infered.rs:10:20
| ...and is captured here
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
| ^^
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the lifetime `'a` as defined on the method body at 10:20
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the lifetime `'a` as defined on the method body at 10:20
|
LL | fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> + 'a {
| ^^^^
Expand Down
16 changes: 5 additions & 11 deletions src/test/ui/issues/issue-16922.stderr
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
error: cannot infer an appropriate lifetime
--> $DIR/issue-16922.rs:4:14
|
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> {
| -- data with this lifetime...
LL | Box::new(value) as Box<dyn Any>
| ---------^^^^^-
| | |
| | ...but this borrow...
| this is `'static`...
| | ...and is captured here
| ...is required to be `'static` by this...
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 3:1
--> $DIR/issue-16922.rs:3:1
|
LL | / fn foo<T: Any>(value: &T) -> Box<dyn Any> {
LL | | Box::new(value) as Box<dyn Any>
LL | |
LL | | }
| |_^
help: you can add a bound to the returned `dyn Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 3:1
help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 3:1
|
LL | fn foo<T: Any>(value: &T) -> Box<dyn Any + '_> {
| ^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
error: cannot infer an appropriate lifetime
--> $DIR/object-lifetime-default-from-box-error.rs:18:5
|
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
| --------------- data with this lifetime...
...
LL | ss.r
| ^^^^ this needs to be `'static` but the borrow...
|
note: ...can't outlive the anonymous lifetime #2 defined on the function body at 14:1
--> $DIR/object-lifetime-default-from-box-error.rs:14:1
| ^^^^ ...is captured and required to be `'static` here
|
LL | / fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> {
LL | | // `Box<SomeTrait>` defaults to a `'static` bound, so this return
LL | | // is illegal.
LL | |
LL | | ss.r
LL | | }
| |_^
help: you can add a bound to the returned `dyn Trait` to make it last less than `'static` and match the anonymous lifetime #2 defined on the function body at 14:1
help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #2 defined on the function body at 14:1
|
LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> {
| ^^^^
Expand Down
18 changes: 6 additions & 12 deletions src/test/ui/regions/region-object-lifetime-in-coercion.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,16 @@ LL | Box::new(v)
error: cannot infer an appropriate lifetime
--> $DIR/region-object-lifetime-in-coercion.rs:20:14
|
LL | fn c(v: &[u8]) -> Box<dyn Foo> {
| ----- data with this lifetime...
...
LL | Box::new(v)
| ---------^-
| | |
| | ...but this borrow...
| this is `'static`...
| | ...and is captured here
| ...is required to be `'static` by this...
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 17:1
--> $DIR/region-object-lifetime-in-coercion.rs:17:1
|
LL | / fn c(v: &[u8]) -> Box<dyn Foo> {
LL | | // same as previous case due to RFC 599
LL | |
LL | | Box::new(v)
LL | | }
| |_^
help: you can add a bound to the returned `dyn Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 17:1
help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 17:1
|
LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> {
| ^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@ error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^^^^ ---------- this is `'static`...
| |
| ...but this borrow...
|
note: ...can't outlive the lifetime `'_` as defined on the method body at 8:26
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:26
|
LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
| ^
| ^^^^ ---------- ---------- ...and required to be `'static` by this
| | |
| | data with this lifetime...
| ...is captured here...

error: aborting due to previous error

Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ error: cannot infer an appropriate lifetime
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:44
|
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
| ---------- ^^^^ ...but this borrow...
| |
| this is `'static`...
| ---------- ---------- ^^^^ ...and is captured here
| | |
| | ...is required to be `'static` by this...
| data with this lifetime...
|
note: ...can't outlive the anonymous lifetime #1 defined on the method body at 6:5
--> $DIR/arbitrary_self_types_pin_lifetime_impl_trait.rs:6:5
|
LL | fn f(self: Pin<&Self>) -> impl Clone { self }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the method body at 6:5
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the method body at 6:5
|
LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
| ^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,16 @@ error: cannot infer an appropriate lifetime
--> $DIR/missing-lifetimes-in-signature.rs:19:5
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
| ------------- this is `'static`...
| ------ ------------- ...is required to be `'static` by this...
| |
| data with this lifetime...
...
LL | / move || {
LL | | *dest = g.get();
LL | | }
| |_____^ ...but this borrow...
| |_____^ ...and is captured here
|
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 15:1
--> $DIR/missing-lifetimes-in-signature.rs:15:1
|
LL | / fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
LL | | where
LL | | G: Get<T>
LL | | {
... |
LL | | }
LL | | }
| |_^
help: you can add a bound to the returned `impl Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 15:1
help: to permit non-static references in an `impl Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 15:1
|
LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
| ^^^^
Expand Down
20 changes: 5 additions & 15 deletions src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
Original file line number Diff line number Diff line change
@@ -1,23 +1,13 @@
error: cannot infer an appropriate lifetime
--> $DIR/dyn-trait-underscore.rs:8:20
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
| ---- data with this lifetime...
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | Box::new(items.iter())
| ---------------^^^^--- this is `'static`...
| ---------------^^^^--- ...is captured and required to be `'static` here
|
note: ...but this borrow...
--> $DIR/dyn-trait-underscore.rs:8:14
|
LL | Box::new(items.iter())
| ^^^^^
note: ...can't outlive the anonymous lifetime #1 defined on the function body at 6:1
--> $DIR/dyn-trait-underscore.rs:6:1
|
LL | / fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | | Box::new(items.iter())
LL | | }
| |_^
help: you can add a bound to the returned `dyn Trait` to make it last less than `'static` and match the anonymous lifetime #1 defined on the function body at 6:1
help: to permit non-static references in a `dyn Trait` value, you can add an explicit bound for the anonymous lifetime #1 defined on the function body at 6:1
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
| ^^^^
Expand Down

0 comments on commit 83f6f22

Please sign in to comment.