Rollup merge of #73496 - estebank:opaque-missing-lts-in-fn-3, r=nikomatsakis
Account for multiple impl/dyn Trait in return type when suggesting `'_` Make `impl` and `dyn` Trait lifetime suggestions a bit more resilient. Follow up to #72804. r? @nikomatsakis
This commit is contained in:
commit
cd18ac1ce8
12 changed files with 367 additions and 79 deletions
|
|
@ -53,7 +53,15 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
|
|||
| help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:33:69
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:30:24
|
||||
|
|
||||
LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
|
||||
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
|
||||
| |
|
||||
| let's call the lifetime of this reference `'1`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:37:69
|
||||
|
|
||||
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
|
||||
| -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static`
|
||||
|
|
@ -62,7 +70,7 @@ LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
|
|||
= help: consider replacing `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:38:61
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:42:61
|
||||
|
|
||||
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
|
||||
| -- -- lifetime `'b` defined here ^^^^^^^^^^^^^^^^ opaque type requires that `'b` must outlive `'a`
|
||||
|
|
@ -72,14 +80,14 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
|
|||
= help: consider adding the following bound: `'b: 'a`
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:43:51
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:47:51
|
||||
|
|
||||
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider adding an explicit lifetime bound `T: 'static`...
|
||||
|
||||
error: aborting due to 8 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0310, E0621.
|
||||
For more information about an error, try `rustc --explain E0310`.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@ fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
|
|||
fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
|
||||
//~^ ERROR cannot infer an appropriate lifetime
|
||||
|
||||
fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
|
||||
//~^ ERROR cannot infer an appropriate lifetime
|
||||
//~| ERROR cannot infer an appropriate lifetime
|
||||
|
||||
trait LifetimeTrait<'a> {}
|
||||
impl<'a> LifetimeTrait<'a> for &'a i32 {}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,13 +87,48 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
|
|||
| help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
|
||||
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:33:69
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:30:65
|
||||
|
|
||||
LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
|
||||
| ---- this data with an anonymous lifetime `'_`... ^ ...is captured here, requiring it to live as long as `'static`
|
||||
|
|
||||
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn elided5(x: &i32) -> (Box<dyn Debug + '_>, impl Debug) { (Box::new(x), x) }
|
||||
| ^^^^
|
||||
help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) }
|
||||
| ^^^^
|
||||
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:30:69
|
||||
|
|
||||
LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
|
||||
| ---- this data with an anonymous lifetime `'_`... ^ ...is captured here...
|
||||
|
|
||||
note: ...and is required to live as long as `'static` here
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:30:41
|
||||
|
|
||||
LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
|
||||
| ^^^^^^^^^^
|
||||
help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn elided5(x: &i32) -> (Box<dyn Debug + '_>, impl Debug) { (Box::new(x), x) }
|
||||
| ^^^^
|
||||
help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) }
|
||||
| ^^^^
|
||||
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:37:69
|
||||
|
|
||||
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
|
||||
| ------- this data with lifetime `'a`... ^ ...is captured here...
|
||||
|
|
||||
note: ...and is required to live as long as `'static` here
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:33:34
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:37:34
|
||||
|
|
||||
LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
@ -107,7 +142,7 @@ LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x
|
|||
| ^^^^^^^^^^^^
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:38:61
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:42:61
|
||||
|
|
||||
LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
|
||||
| ------- ^^^^^^^^^^^^^^^^
|
||||
|
|
@ -116,7 +151,7 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
|
|||
| this parameter and the return type are declared with different lifetimes...
|
||||
|
||||
error[E0310]: the parameter type `T` may not live long enough
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:43:51
|
||||
--> $DIR/must_outlive_least_region_or_bound.rs:47:51
|
||||
|
|
||||
LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static {
|
||||
| -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
||||
|
|
@ -181,7 +216,7 @@ help: alternatively, add an explicit `'static` bound to this reference
|
|||
LL | fn explicit4<'a>(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0310, E0621, E0623, E0759.
|
||||
For more information about an error, try `rustc --explain E0310`.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ LL | async fn f(self: Pin<&Self>) -> impl Clone { self }
|
|||
| | |
|
||||
| | this data with an anonymous lifetime `'_`...
|
||||
| ...is captured here...
|
||||
|
|
||||
help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self }
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
error: lifetime may not live long enough
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:27:23
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
|
||||
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static`
|
||||
| |
|
||||
| let's call the lifetime of this reference `'1`
|
||||
|
|
||||
help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:39:9
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
|
||||
| - let's call the lifetime of this reference `'1`
|
||||
LL | / Iter {
|
||||
LL | | current: None,
|
||||
LL | | remaining: self.0.iter(),
|
||||
LL | | }
|
||||
| |_________^ returning this value requires that `'1` must outlive `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:50:9
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | / Iter {
|
||||
LL | | current: None,
|
||||
LL | | remaining: self.0.iter(),
|
||||
LL | | }
|
||||
| |_________^ returning this value requires that `'a` must outlive `'static`
|
||||
|
|
||||
= help: consider replacing `'a` with `'static`
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:60:30
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
|
||||
| -- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static`
|
||||
| |
|
||||
| lifetime `'a` defined here
|
||||
|
|
||||
= help: consider replacing `'a` with `'static`
|
||||
help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
trait Foo {}
|
||||
impl<'a, T: Foo> Foo for &'a T {}
|
||||
impl<T: Foo + ?Sized> Foo for Box<T> {}
|
||||
|
||||
struct Iter<'a, T> {
|
||||
current: Option<Box<dyn Foo + 'a>>,
|
||||
remaining: T,
|
||||
}
|
||||
|
||||
impl<'a, T> Iterator for Iter<'a, T>
|
||||
where
|
||||
T: Iterator,
|
||||
T::Item: Foo + 'a,
|
||||
{
|
||||
type Item = Box<dyn Foo + 'a>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let result = self.current.take();
|
||||
self.current = Box::new(self.remaining.next()).map(|f| Box::new(f) as _);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar(Vec<Box<dyn Foo>>);
|
||||
|
||||
impl Bar {
|
||||
fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
|
||||
Iter {
|
||||
current: None,
|
||||
remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Baz(Vec<Box<dyn Foo>>);
|
||||
|
||||
impl Baz {
|
||||
fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
|
||||
Iter {
|
||||
current: None,
|
||||
remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Bat(Vec<Box<dyn Foo>>);
|
||||
|
||||
impl Bat {
|
||||
fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
|
||||
Iter {
|
||||
current: None,
|
||||
remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Ban(Vec<Box<dyn Foo>>);
|
||||
|
||||
impl Ban {
|
||||
fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
|
||||
Iter {
|
||||
current: None,
|
||||
remaining: self.0.iter(), //~ ERROR cannot infer an appropriate lifetime
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:30:31
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
|
||||
| ----- this data with an anonymous lifetime `'_`...
|
||||
...
|
||||
LL | remaining: self.0.iter(),
|
||||
| ------ ^^^^
|
||||
| |
|
||||
| ...is captured here...
|
||||
|
|
||||
note: ...and is required to live as long as `'static` here
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:27:23
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
|
||||
| ^^^^
|
||||
help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> {
|
||||
| ^^^^
|
||||
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:41:31
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
|
||||
| ----- this data with an anonymous lifetime `'_`...
|
||||
...
|
||||
LL | remaining: self.0.iter(),
|
||||
| ------ ^^^^
|
||||
| |
|
||||
| ...is captured here...
|
||||
|
|
||||
note: ...and is required to live as long as `'static` here
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:38:23
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound
|
||||
|
|
||||
LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> + '_ {
|
||||
| ^^^^
|
||||
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:52:31
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
|
||||
| -------- this data with lifetime `'a`...
|
||||
...
|
||||
LL | remaining: self.0.iter(),
|
||||
| ------ ^^^^
|
||||
| |
|
||||
| ...is captured here...
|
||||
|
|
||||
note: ...and is required to live as long as `'static` here
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:49:30
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> + 'a {
|
||||
| ^^^^
|
||||
|
||||
error[E0759]: cannot infer an appropriate lifetime
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:63:31
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
|
||||
| -------- this data with lifetime `'a`...
|
||||
...
|
||||
LL | remaining: self.0.iter(),
|
||||
| ------ ^^^^
|
||||
| |
|
||||
| ...is captured here...
|
||||
|
|
||||
note: ...and is required to live as long as `'static` here
|
||||
--> $DIR/trait-object-nested-in-impl-trait.rs:60:30
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
|
||||
| ^^^^
|
||||
help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound
|
||||
|
|
||||
LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> {
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0759`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue