summaryrefslogtreecommitdiffstats
path: root/tests/ui/suggestions/lifetimes
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/suggestions/lifetimes
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/suggestions/lifetimes')
-rw-r--r--tests/ui/suggestions/lifetimes/issue-105544.fixed45
-rw-r--r--tests/ui/suggestions/lifetimes/issue-105544.rs45
-rw-r--r--tests/ui/suggestions/lifetimes/issue-105544.stderr110
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed29
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs29
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr30
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.fixed10
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.rs10
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.stderr15
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs111
-rw-r--r--tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr168
-rw-r--r--tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs72
-rw-r--r--tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr78
13 files changed, 752 insertions, 0 deletions
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.fixed b/tests/ui/suggestions/lifetimes/issue-105544.fixed
new file mode 100644
index 000000000..47087eb47
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.fixed
@@ -0,0 +1,45 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn foo<'a>(d: impl Sized + 'a, p: &'a mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+ (d, p)
+ //~^ ERROR the parameter type `impl Sized` may not live long enough
+ //~| NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+}
+
+fn foo1<'b>(d: impl Sized + 'b, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+ (d, p) //~ NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+ //~^ ERROR the parameter type `impl Sized` may not live long enough
+}
+
+fn foo2<'b, 'a>(d: impl Sized + 'a + 'b, p: &'b mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+ (d, p)
+ //~^ ERROR the parameter type `impl Sized + 'a` may not live long enough
+ //~| NOTE ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+}
+
+fn bar<'a, T : Sized + 'a>(d: T, p: &'a mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+ (d, p)
+ //~^ ERROR the parameter type `T` may not live long enough
+ //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn bar1<'b, T : Sized + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+ (d, p) //~ NOTE ...so that the type `T` will meet its required lifetime bounds
+ //~^ ERROR the parameter type `T` may not live long enough
+}
+
+fn bar2<'b, 'a, T : Sized + 'a + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+ (d, p)
+ //~^ ERROR the parameter type `T` may not live long enough
+ //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.rs b/tests/ui/suggestions/lifetimes/issue-105544.rs
new file mode 100644
index 000000000..bd3bc1ef9
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.rs
@@ -0,0 +1,45 @@
+// run-rustfix
+
+#![allow(warnings)]
+
+fn foo(d: impl Sized, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+ (d, p)
+ //~^ ERROR the parameter type `impl Sized` may not live long enough
+ //~| NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+}
+
+fn foo1<'b>(d: impl Sized, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+ (d, p) //~ NOTE ...so that the type `impl Sized` will meet its required lifetime bounds
+ //~^ ERROR the parameter type `impl Sized` may not live long enough
+}
+
+fn foo2<'a>(d: impl Sized + 'a, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+ (d, p)
+ //~^ ERROR the parameter type `impl Sized + 'a` may not live long enough
+ //~| NOTE ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+}
+
+fn bar<T : Sized>(d: T, p: & mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+ (d, p)
+ //~^ ERROR the parameter type `T` may not live long enough
+ //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn bar1<'b, T : Sized>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+//~^ HELP consider adding an explicit lifetime bound...
+ (d, p) //~ NOTE ...so that the type `T` will meet its required lifetime bounds
+ //~^ ERROR the parameter type `T` may not live long enough
+}
+
+fn bar2<'a, T : Sized + 'a>(d: T, p: &mut ()) -> impl Sized + '_ { //~ NOTE the parameter type `T` must be valid for the anonymous lifetime defined here...
+//~^ HELP consider adding an explicit lifetime bound
+ (d, p)
+ //~^ ERROR the parameter type `T` may not live long enough
+ //~| NOTE ...so that the type `T` will meet its required lifetime bounds
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/issue-105544.stderr b/tests/ui/suggestions/lifetimes/issue-105544.stderr
new file mode 100644
index 000000000..08fe21b11
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/issue-105544.stderr
@@ -0,0 +1,110 @@
+error[E0311]: the parameter type `impl Sized` may not live long enough
+ --> $DIR/issue-105544.rs:7:5
+ |
+LL | (d, p)
+ | ^^^^^^
+ |
+note: the parameter type `impl Sized` must be valid for the anonymous lifetime defined here...
+ --> $DIR/issue-105544.rs:5:26
+ |
+LL | fn foo(d: impl Sized, p: &mut ()) -> impl Sized + '_ {
+ | ^^^^^^^
+note: ...so that the type `impl Sized` will meet its required lifetime bounds
+ --> $DIR/issue-105544.rs:7:5
+ |
+LL | (d, p)
+ | ^^^^^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn foo<'a>(d: impl Sized + 'a, p: &'a mut ()) -> impl Sized + '_ {
+ | ++++ ++++ ++
+
+error[E0309]: the parameter type `impl Sized` may not live long enough
+ --> $DIR/issue-105544.rs:14:5
+ |
+LL | (d, p)
+ | ^^^^^^ ...so that the type `impl Sized` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn foo1<'b>(d: impl Sized + 'b, p: &'b mut ()) -> impl Sized + '_ {
+ | ++++
+
+error[E0311]: the parameter type `impl Sized + 'a` may not live long enough
+ --> $DIR/issue-105544.rs:20:5
+ |
+LL | (d, p)
+ | ^^^^^^
+ |
+note: the parameter type `impl Sized + 'a` must be valid for the anonymous lifetime defined here...
+ --> $DIR/issue-105544.rs:18:36
+ |
+LL | fn foo2<'a>(d: impl Sized + 'a, p: &mut ()) -> impl Sized + '_ {
+ | ^^^^^^^
+note: ...so that the type `impl Sized + 'a` will meet its required lifetime bounds
+ --> $DIR/issue-105544.rs:20:5
+ |
+LL | (d, p)
+ | ^^^^^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn foo2<'b, 'a>(d: impl Sized + 'a + 'b, p: &'b mut ()) -> impl Sized + '_ {
+ | +++ ++++ ++
+
+error[E0311]: the parameter type `T` may not live long enough
+ --> $DIR/issue-105544.rs:27:5
+ |
+LL | (d, p)
+ | ^^^^^^
+ |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+ --> $DIR/issue-105544.rs:25:28
+ |
+LL | fn bar<T : Sized>(d: T, p: & mut ()) -> impl Sized + '_ {
+ | ^^^^^^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+ --> $DIR/issue-105544.rs:27:5
+ |
+LL | (d, p)
+ | ^^^^^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn bar<'a, T : Sized + 'a>(d: T, p: &'a mut ()) -> impl Sized + '_ {
+ | +++ ++++ ++
+
+error[E0309]: the parameter type `T` may not live long enough
+ --> $DIR/issue-105544.rs:34:5
+ |
+LL | (d, p)
+ | ^^^^^^ ...so that the type `T` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn bar1<'b, T : Sized + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+ | ++++
+
+error[E0311]: the parameter type `T` may not live long enough
+ --> $DIR/issue-105544.rs:40:5
+ |
+LL | (d, p)
+ | ^^^^^^
+ |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+ --> $DIR/issue-105544.rs:38:38
+ |
+LL | fn bar2<'a, T : Sized + 'a>(d: T, p: &mut ()) -> impl Sized + '_ {
+ | ^^^^^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+ --> $DIR/issue-105544.rs:40:5
+ |
+LL | (d, p)
+ | ^^^^^^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn bar2<'b, 'a, T : Sized + 'a + 'b>(d: T, p: &'b mut ()) -> impl Sized + '_ {
+ | +++ ++++ ++
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0309, E0311.
+For more information about an error, try `rustc --explain E0309`.
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed
new file mode 100644
index 000000000..4013d98c3
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.fixed
@@ -0,0 +1,29 @@
+// Regression test for #81650
+// run-rustfix
+
+#![allow(warnings)]
+
+struct Foo<'a> {
+ x: &'a mut &'a i32,
+}
+
+impl<'a> Foo<'a> {
+ fn bar<F, T>(&self, f: F)
+ where
+ F: FnOnce(&Foo<'a>) -> T,
+ F: 'a,
+ {}
+}
+
+trait Test {
+ fn test(&self);
+}
+
+fn func<'a, T: Test + 'a>(foo: &'a Foo<'a>, t: T) {
+ foo.bar(move |_| {
+ //~^ ERROR the parameter type `T` may not live long enough
+ t.test();
+ });
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs
new file mode 100644
index 000000000..4096d95e5
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.rs
@@ -0,0 +1,29 @@
+// Regression test for #81650
+// run-rustfix
+
+#![allow(warnings)]
+
+struct Foo<'a> {
+ x: &'a mut &'a i32,
+}
+
+impl<'a> Foo<'a> {
+ fn bar<F, T>(&self, f: F)
+ where
+ F: FnOnce(&Foo<'a>) -> T,
+ F: 'a,
+ {}
+}
+
+trait Test {
+ fn test(&self);
+}
+
+fn func<T: Test>(foo: &Foo, t: T) {
+ foo.bar(move |_| {
+ //~^ ERROR the parameter type `T` may not live long enough
+ t.test();
+ });
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
new file mode 100644
index 000000000..936d87f79
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr
@@ -0,0 +1,30 @@
+error[E0311]: the parameter type `T` may not live long enough
+ --> $DIR/missing-lifetimes-in-signature-2.rs:23:5
+ |
+LL | / foo.bar(move |_| {
+LL | |
+LL | | t.test();
+LL | | });
+ | |______^
+ |
+note: the parameter type `T` must be valid for the anonymous lifetime defined here...
+ --> $DIR/missing-lifetimes-in-signature-2.rs:22:24
+ |
+LL | fn func<T: Test>(foo: &Foo, t: T) {
+ | ^^^
+note: ...so that the type `T` will meet its required lifetime bounds
+ --> $DIR/missing-lifetimes-in-signature-2.rs:23:5
+ |
+LL | / foo.bar(move |_| {
+LL | |
+LL | | t.test();
+LL | | });
+ | |______^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn func<'a, T: Test + 'a>(foo: &'a Foo<'a>, t: T) {
+ | +++ ++++ ++ ++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0311`.
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.fixed b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.fixed
new file mode 100644
index 000000000..3c06f4f88
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.fixed
@@ -0,0 +1,10 @@
+// run-rustfix
+// https://github.com/rust-lang/rust/issues/95616
+
+fn buggy_const<'a, const N: usize>(_a: &'a Option<[u8; N]>, _f: &'a str) -> &'a str { //~ERROR [E0106]
+ return "";
+}
+
+fn main() {
+ buggy_const(&Some([69,69,69,69,0]), "test");
+}
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.rs
new file mode 100644
index 000000000..110468cbb
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.rs
@@ -0,0 +1,10 @@
+// run-rustfix
+// https://github.com/rust-lang/rust/issues/95616
+
+fn buggy_const<const N: usize>(_a: &Option<[u8; N]>, _f: &str) -> &str { //~ERROR [E0106]
+ return "";
+}
+
+fn main() {
+ buggy_const(&Some([69,69,69,69,0]), "test");
+}
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.stderr
new file mode 100644
index 000000000..7b126c90e
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature-before-const.stderr
@@ -0,0 +1,15 @@
+error[E0106]: missing lifetime specifier
+ --> $DIR/missing-lifetimes-in-signature-before-const.rs:4:67
+ |
+LL | fn buggy_const<const N: usize>(_a: &Option<[u8; N]>, _f: &str) -> &str {
+ | ---------------- ---- ^ expected named lifetime parameter
+ |
+ = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_a` or `_f`
+help: consider introducing a named lifetime parameter
+ |
+LL | fn buggy_const<'a, const N: usize>(_a: &'a Option<[u8; N]>, _f: &'a str) -> &'a str {
+ | +++ ++ ++ ++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
new file mode 100644
index 000000000..b641f5941
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs
@@ -0,0 +1,111 @@
+pub trait Get<T> {
+ fn get(self) -> T;
+}
+
+struct Foo {
+ x: usize,
+}
+
+impl Get<usize> for Foo {
+ fn get(self) -> usize {
+ self.x
+ }
+}
+
+fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
+where
+ G: Get<T>,
+{
+ move || {
+ //~^ ERROR hidden type for `impl FnOnce()` captures lifetime
+ *dest = g.get();
+ }
+}
+
+// After applying suggestion for `foo`:
+fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+where
+ G: Get<T>,
+{
+ move || {
+ //~^ ERROR the parameter type `G` may not live long enough
+ *dest = g.get();
+ }
+}
+
+// After applying suggestion for `bar`:
+fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+//~^ ERROR undeclared lifetime name `'a`
+where
+ G: Get<T>,
+{
+ move || {
+ *dest = g.get();
+ }
+}
+
+// After applying suggestion for `baz`:
+fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+where
+ G: Get<T>,
+{
+ move || {
+ //~^ ERROR the parameter type `G` may not live long enough
+ *dest = g.get();
+ }
+}
+
+// Same as above, but show that we pay attention to lifetime names from parent item
+impl<'a> Foo {
+ fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+ move || {
+ //~^ ERROR the parameter type `G` may not live long enough
+ *dest = g.get();
+ }
+ }
+}
+
+// After applying suggestion for `qux`:
+fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+where
+ G: Get<T>,
+{
+ move || {
+ //~^ ERROR the parameter type `G` may not live long enough
+ //~| ERROR explicit lifetime required
+ *dest = g.get();
+ }
+}
+
+// Potential incorrect attempt:
+fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
+where
+ G: Get<T>,
+{
+ move || {
+ //~^ ERROR the parameter type `G` may not live long enough
+ *dest = g.get();
+ }
+}
+
+// We need to tie the lifetime of `G` with the lifetime of `&mut T` and the returned closure:
+fn ok<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a
+where
+ G: Get<T>,
+{
+ move || {
+ *dest = g.get();
+ }
+}
+
+// This also works. The `'_` isn't necessary but it's where we arrive to following the suggestions:
+fn ok2<'a, G: 'a, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_ + 'a
+where
+ G: Get<T>,
+{
+ move || {
+ *dest = g.get();
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
new file mode 100644
index 000000000..c5c3f7b46
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr
@@ -0,0 +1,168 @@
+error[E0261]: use of undeclared lifetime name `'a`
+ --> $DIR/missing-lifetimes-in-signature.rs:37:11
+ |
+LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+ | - ^^ undeclared lifetime
+ | |
+ | help: consider introducing lifetime `'a` here: `'a,`
+
+error[E0700]: hidden type for `impl FnOnce()` captures lifetime that does not appear in bounds
+ --> $DIR/missing-lifetimes-in-signature.rs:19:5
+ |
+LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce()
+ | ------ hidden type `[closure@$DIR/missing-lifetimes-in-signature.rs:19:5: 19:12]` captures the anonymous lifetime defined here
+...
+LL | / move || {
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^
+ |
+help: to declare that `impl FnOnce()` captures `'_`, you can add an explicit `'_` lifetime bound
+ |
+LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+ | ++++
+
+error[E0311]: the parameter type `G` may not live long enough
+ --> $DIR/missing-lifetimes-in-signature.rs:30:5
+ |
+LL | / move || {
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^
+ |
+note: the parameter type `G` must be valid for the anonymous lifetime defined here...
+ --> $DIR/missing-lifetimes-in-signature.rs:26:26
+ |
+LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+ | ^^^^^^
+note: ...so that the type `G` will meet its required lifetime bounds
+ --> $DIR/missing-lifetimes-in-signature.rs:30:5
+ |
+LL | / move || {
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^
+help: consider adding an explicit lifetime bound...
+ |
+LL ~ fn bar<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + '_
+LL | where
+LL ~ G: Get<T> + 'a,
+ |
+
+error[E0311]: the parameter type `G` may not live long enough
+ --> $DIR/missing-lifetimes-in-signature.rs:52:5
+ |
+LL | / move || {
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^
+ |
+note: the parameter type `G` must be valid for the anonymous lifetime defined here...
+ --> $DIR/missing-lifetimes-in-signature.rs:48:34
+ |
+LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_
+ | ^^^^^^
+note: ...so that the type `G` will meet its required lifetime bounds
+ --> $DIR/missing-lifetimes-in-signature.rs:52:5
+ |
+LL | / move || {
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + '_
+ | +++ ++++ ++
+
+error[E0311]: the parameter type `G` may not live long enough
+ --> $DIR/missing-lifetimes-in-signature.rs:61:9
+ |
+LL | / move || {
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_________^
+ |
+note: the parameter type `G` must be valid for the anonymous lifetime defined here...
+ --> $DIR/missing-lifetimes-in-signature.rs:60:47
+ |
+LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ {
+ | ^^^^^^
+note: ...so that the type `G` will meet its required lifetime bounds
+ --> $DIR/missing-lifetimes-in-signature.rs:61:9
+ |
+LL | / move || {
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_________^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn qux<'c, 'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &'c mut T) -> impl FnOnce() + '_ {
+ | +++ ++++ ++
+
+error[E0311]: the parameter type `G` may not live long enough
+ --> $DIR/missing-lifetimes-in-signature.rs:73:5
+ |
+LL | / move || {
+LL | |
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^
+ |
+note: the parameter type `G` must be valid for the anonymous lifetime defined here...
+ --> $DIR/missing-lifetimes-in-signature.rs:69:34
+ |
+LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+ | ^^^^^^
+note: ...so that the type `G` will meet its required lifetime bounds
+ --> $DIR/missing-lifetimes-in-signature.rs:73:5
+ |
+LL | / move || {
+LL | |
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^
+help: consider adding an explicit lifetime bound...
+ |
+LL | fn bat<'b, 'a, G: 'a + 'b, T>(g: G, dest: &'b mut T) -> impl FnOnce() + '_ + 'a
+ | +++ ++++ ++
+
+error[E0621]: explicit lifetime required in the type of `dest`
+ --> $DIR/missing-lifetimes-in-signature.rs:73:5
+ |
+LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
+ | ------ help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
+...
+LL | / move || {
+LL | |
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^ lifetime `'a` required
+
+error[E0309]: the parameter type `G` may not live long enough
+ --> $DIR/missing-lifetimes-in-signature.rs:85:5
+ |
+LL | / move || {
+LL | |
+LL | | *dest = g.get();
+LL | | }
+ | |_____^ ...so that the type `G` will meet its required lifetime bounds
+ |
+help: consider adding an explicit lifetime bound...
+ |
+LL | G: Get<T> + 'a,
+ | ++++
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0261, E0309, E0311, E0621, E0700.
+For more information about an error, try `rustc --explain E0261`.
diff --git a/tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs b/tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs
new file mode 100644
index 000000000..ff27011f8
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.rs
@@ -0,0 +1,72 @@
+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 {
+ //~^ ERROR lifetime may not live long enough
+ current: None,
+ remaining: self.0.iter(),
+ }
+ }
+}
+
+struct Baz(Vec<Box<dyn Foo>>);
+
+impl Baz {
+ fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+ Iter {
+ //~^ ERROR lifetime may not live long enough
+ current: None,
+ remaining: self.0.iter(),
+ }
+ }
+}
+
+struct Bat(Vec<Box<dyn Foo>>);
+
+impl Bat {
+ fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+ Iter {
+ //~^ ERROR lifetime may not live long enough
+ current: None,
+ remaining: self.0.iter(),
+ }
+ }
+}
+
+struct Ban(Vec<Box<dyn Foo>>);
+
+impl Ban {
+ fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
+ Iter {
+ //~^ ERROR lifetime may not live long enough
+ current: None,
+ remaining: self.0.iter(),
+ }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr b/tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr
new file mode 100644
index 000000000..c77ef79e7
--- /dev/null
+++ b/tests/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.stderr
@@ -0,0 +1,78 @@
+error: lifetime may not live long enough
+ --> $DIR/trait-object-nested-in-impl-trait.rs:28:9
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> {
+ | - let's call the lifetime of this reference `'1`
+LL | / Iter {
+LL | |
+LL | | current: None,
+LL | | remaining: self.0.iter(),
+LL | | }
+ | |_________^ returning this value requires that `'1` must outlive `'static`
+ |
+help: to declare that `impl Iterator<Item = Box<(dyn Foo + 'static)>>` 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: lifetime may not live long enough
+ --> $DIR/trait-object-nested-in-impl-trait.rs:40:9
+ |
+LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ {
+ | - let's call the lifetime of this reference `'1`
+LL | / Iter {
+LL | |
+LL | | current: None,
+LL | | remaining: self.0.iter(),
+LL | | }
+ | |_________^ returning this value requires that `'1` must outlive `'static`
+ |
+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: lifetime may not live long enough
+ --> $DIR/trait-object-nested-in-impl-trait.rs:52:9
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a {
+ | -- lifetime `'a` defined here
+LL | / Iter {
+LL | |
+LL | | current: None,
+LL | | remaining: self.0.iter(),
+LL | | }
+ | |_________^ returning this value requires that `'a` must outlive `'static`
+ |
+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: lifetime may not live long enough
+ --> $DIR/trait-object-nested-in-impl-trait.rs:64:9
+ |
+LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> {
+ | -- lifetime `'a` defined here
+LL | / Iter {
+LL | |
+LL | | current: None,
+LL | | remaining: self.0.iter(),
+LL | | }
+ | |_________^ returning this value requires that `'a` must outlive `'static`
+ |
+help: to declare that `impl Iterator<Item = Box<(dyn Foo + 'static)>>` 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
+