about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-06-23 00:33:58 -0700
committerGitHub <noreply@github.com>2020-06-23 00:33:58 -0700
commitcd18ac1ce8f256801b69b9cd1df92bf975f85bc4 (patch)
treed553426f2d7f554cf7cf45a6e017eec6322c5b22 /src/test
parent98aa34cb574513903bf9a59a4147a362132779c2 (diff)
parent3eb8eb942951d66fe1f0cc1be3a47cd9f147fc3e (diff)
downloadrust-cd18ac1ce8f256801b69b9cd1df92bf975f85bc4.tar.gz
rust-cd18ac1ce8f256801b69b9cd1df92bf975f85bc4.zip
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
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr16
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs4
-rw-r--r--src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr45
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr5
-rw-r--r--src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr53
-rw-r--r--src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs68
-rw-r--r--src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr95
7 files changed, 277 insertions, 9 deletions
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
index ca9ca8a9deb..3b339c5c3d7 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr
@@ -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`.
diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
index 837244b0227..9bf86fa66cd 100644
--- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
+++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs
@@ -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 {}
 
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 e1fa4f02b6f..ffadcaae08e 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
@@ -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`.
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
index 88bd990b1e8..f2fbb0ba7d7 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr
@@ -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
 
diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
new file mode 100644
index 00000000000..2407d13714a
--- /dev/null
+++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr
@@ -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
+
diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs
new file mode 100644
index 00000000000..f78edb1c83a
--- /dev/null
+++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs
@@ -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() {}
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
new file mode 100644
index 00000000000..1257e9b172c
--- /dev/null
+++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr
@@ -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`.