about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-12 21:42:10 +0000
committerbors <bors@rust-lang.org>2022-02-12 21:42:10 +0000
commit3cfa4def7c87d571bd46d92fed608edf8fad236e (patch)
tree43fadb34acfa47419ac74221dbca1161938dbeee /src
parent5d8767cb229b097fedb1dd4bd9420d463c37774f (diff)
parent10cf626d0ea7be3eb971691772b5eb30013d4f02 (diff)
downloadrust-3cfa4def7c87d571bd46d92fed608edf8fad236e.tar.gz
rust-3cfa4def7c87d571bd46d92fed608edf8fad236e.zip
Auto merge of #91403 - cjgillot:inherit-async, r=oli-obk
Inherit lifetimes for async fn instead of duplicating them.

The current desugaring of `async fn foo<'a>(&usize) -> &u8` is equivalent to
```rust
fn foo<'a, '0>(&'0 usize) -> foo<'static, 'static>::Opaque<'a, '0, '_>;
type foo<'_a, '_0>::Opaque<'a, '0, '1> = impl Future<Output = &'1 u8>;
```
following the RPIT model.

Duplicating all the inherited lifetime parameters and setting the inherited version to `'static` makes lowering more complex and causes issues like #61949. This PR removes the duplication of inherited lifetimes to directly use
```rust
fn foo<'a, '0>(&'0 usize) -> foo<'a, '0>::Opaque<'_>;
type foo<'a, '0>::Opaque<'1> = impl Future<Output = &'1 u8>;
```
following the TAIT model.

Fixes https://github.com/rust-lang/rust/issues/61949
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/mod.rs7
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.rs2
-rw-r--r--src/test/ui/async-await/issue-61949-self-return-type.stderr16
-rw-r--r--src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr4
-rw-r--r--src/test/ui/async-await/issue-75785-confusing-named-region.stderr4
-rw-r--r--src/test/ui/async-await/issues/issue-63388-1.stderr8
-rw-r--r--src/test/ui/async-await/issues/issue-78600.rs2
-rw-r--r--src/test/ui/async-await/issues/issue-78600.stderr11
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr18
-rw-r--r--src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr7
-rw-r--r--src/test/ui/async-await/unused-lifetime.rs3
-rw-r--r--src/test/ui/async-await/unused-lifetime.stderr34
-rw-r--r--src/test/ui/dropck/drop-with-active-borrows-2.stderr5
-rw-r--r--src/test/ui/issues/issue-13497-2.rs4
-rw-r--r--src/test/ui/issues/issue-13497-2.stderr14
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr5
-rw-r--r--src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr12
-rw-r--r--src/test/ui/self/elision/lt-ref-self-async.stderr36
-rw-r--r--src/test/ui/self/elision/ref-mut-self-async.stderr36
-rw-r--r--src/test/ui/self/elision/ref-mut-struct-async.stderr30
-rw-r--r--src/test/ui/self/elision/ref-self-async.stderr42
-rw-r--r--src/test/ui/self/elision/ref-struct-async.stderr30
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.stderr2
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.stderr8
26 files changed, 149 insertions, 193 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index f54fb4af261..e34faef9d6d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -585,7 +585,12 @@ fn clean_ty_generics(
         .params
         .iter()
         .filter_map(|param| match param.kind {
-            ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
+            ty::GenericParamDefKind::Lifetime => {
+                if param.name == kw::UnderscoreLifetime {
+                    return None;
+                }
+                Some(param.clean(cx))
+            }
             ty::GenericParamDefKind::Type { synthetic, .. } => {
                 if param.name == kw::SelfUpper {
                     assert_eq!(param.index, 0);
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs
index 43429ba2329..42133d51041 100644
--- a/src/test/ui/async-await/issue-61949-self-return-type.rs
+++ b/src/test/ui/async-await/issue-61949-self-return-type.rs
@@ -8,7 +8,6 @@ pub struct Foo<'a> {
 
 impl<'a> Foo<'a> {
     pub async fn new(_bar: &'a i32) -> Self {
-    //~^ ERROR `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
         Foo {
             bar: &22
         }
@@ -19,6 +18,7 @@ async fn foo() {
     let x = {
         let bar = 22;
         Foo::new(&bar).await
+        //~^ ERROR `bar` does not live long enough [E0597]
     };
     drop(x);
 }
diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr
index 52b726e186e..f86844e1a9c 100644
--- a/src/test/ui/async-await/issue-61949-self-return-type.stderr
+++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr
@@ -1,9 +1,15 @@
-error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/issue-61949-self-return-type.rs:10:40
+error[E0597]: `bar` does not live long enough
+  --> $DIR/issue-61949-self-return-type.rs:20:18
    |
-LL |     pub async fn new(_bar: &'a i32) -> Self {
-   |                                        ^^^^ help: consider spelling out the type instead: `Foo<'a>`
+LL |     let x = {
+   |         - borrow later stored here
+LL |         let bar = 22;
+LL |         Foo::new(&bar).await
+   |                  ^^^^ borrowed value does not live long enough
+LL |
+LL |     };
+   |     - `bar` dropped here while still borrowed
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0760`.
+For more information about this error, try `rustc --explain E0597`.
diff --git a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
index b96cab9f0f5..80504613eb4 100644
--- a/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
+++ b/src/test/ui/async-await/issue-74072-lifetime-name-annotations.stderr
@@ -1,14 +1,10 @@
 error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-74072-lifetime-name-annotations.rs:9:5
    |
-LL | pub async fn async_fn(x: &mut i32) -> &i32 {
-   |                          - let's call the lifetime of this reference `'1`
 LL |     let y = &*x;
    |             --- borrow of `*x` occurs here
 LL |     *x += 1;
    |     ^^^^^^^ assignment to borrowed `*x` occurs here
-LL |     y
-   |     - returning this value requires that `*x` is borrowed for `'1`
 
 error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-74072-lifetime-name-annotations.rs:16:9
diff --git a/src/test/ui/async-await/issue-75785-confusing-named-region.stderr b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
index 3b731d9c60a..06660b7c182 100644
--- a/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
+++ b/src/test/ui/async-await/issue-75785-confusing-named-region.stderr
@@ -1,14 +1,10 @@
 error[E0506]: cannot assign to `*x` because it is borrowed
   --> $DIR/issue-75785-confusing-named-region.rs:9:5
    |
-LL | pub async fn async_fn(x: &mut i32) -> (&i32, &i32) {
-   |                          - let's call the lifetime of this reference `'1`
 LL |     let y = &*x;
    |             --- borrow of `*x` occurs here
 LL |     *x += 1;
    |     ^^^^^^^ assignment to borrowed `*x` occurs here
-LL |     (&32, y)
-   |     -------- returning this value requires that `*x` is borrowed for `'1`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr
index 8f602a1492a..ee270d36979 100644
--- a/src/test/ui/async-await/issues/issue-63388-1.stderr
+++ b/src/test/ui/async-await/issues/issue-63388-1.stderr
@@ -2,12 +2,10 @@ error[E0623]: lifetime mismatch
   --> $DIR/issue-63388-1.rs:14:9
    |
 LL |         &'a self, foo: &dyn Foo
-   |                        -------- this parameter and the return type are declared with different lifetimes...
-LL |     ) -> &dyn Foo
-   |          --------
-LL |     {
+   |         --------       -------- these two types are declared with different lifetimes...
+...
 LL |         foo
-   |         ^^^ ...but data from `foo` is returned here
+   |         ^^^ ...but data from `foo` flows into `self` here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/issues/issue-78600.rs b/src/test/ui/async-await/issues/issue-78600.rs
index 8aaeaecf3e1..4303fc7952f 100644
--- a/src/test/ui/async-await/issues/issue-78600.rs
+++ b/src/test/ui/async-await/issues/issue-78600.rs
@@ -1,10 +1,10 @@
+// check-pass
 // edition:2018
 
 struct S<'a>(&'a i32);
 
 impl<'a> S<'a> {
     async fn new(i: &'a i32) -> Result<Self, ()> {
-        //~^ ERROR: `async fn`
         Ok(S(&22))
     }
 }
diff --git a/src/test/ui/async-await/issues/issue-78600.stderr b/src/test/ui/async-await/issues/issue-78600.stderr
deleted file mode 100644
index 92b66147106..00000000000
--- a/src/test/ui/async-await/issues/issue-78600.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0760]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/issue-78600.rs:6:33
-   |
-LL |     async fn new(i: &'a i32) -> Result<Self, ()> {
-   |                                 ^^^^^^^----^^^^^
-   |                                        |
-   |                                        help: consider spelling out the type instead: `S<'a>`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0760`.
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
index 2722c72c20a..b0ea6af0050 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.nll.stderr
@@ -1,15 +1,13 @@
 error: lifetime may not live long enough
-  --> $DIR/ret-impl-trait-one.rs:10:85
+  --> $DIR/ret-impl-trait-one.rs:12:5
    |
-LL |   async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
-   |  ________________________________--__--_______________________________________________^
-   | |                                |   |
-   | |                                |   lifetime `'b` defined here
-   | |                                lifetime `'a` defined here
-LL | |
-LL | |     (a, b)
-LL | | }
-   | |_^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
+   |                                --  -- lifetime `'b` defined here
+   |                                |
+   |                                lifetime `'a` defined here
+LL |
+LL |     (a, b)
+   |     ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
    |
    = help: consider adding the following bound: `'a: 'b`
 
diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
index 149692a2c69..6f79d9e9b5f 100644
--- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
+++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.stderr
@@ -2,10 +2,9 @@ error[E0623]: lifetime mismatch
   --> $DIR/ret-impl-trait-one.rs:10:65
    |
 LL | async fn async_ret_impl_trait3<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a> + 'b {
-   |                                                      ------     ^^^^^^^^^^^^^^^^^^^
-   |                                                      |          |
-   |                                                      |          ...but data from `a` is returned here
-   |                                                      this parameter and the return type are declared with different lifetimes...
+   |                                           ------     ------     ^^^^^^^^^^^^^^^^^^^ ...but data from `a` flows into `b` here
+   |                                           |
+   |                                           these two types are declared with different lifetimes...
 
 error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
   --> $DIR/ret-impl-trait-one.rs:16:65
diff --git a/src/test/ui/async-await/unused-lifetime.rs b/src/test/ui/async-await/unused-lifetime.rs
index 5bd6ae8d3a4..a0504927254 100644
--- a/src/test/ui/async-await/unused-lifetime.rs
+++ b/src/test/ui/async-await/unused-lifetime.rs
@@ -10,10 +10,13 @@
 // Even wrong cases don't cause errors because async functions are desugared with all lifetimes
 // involved in the signature. So, we cannot predict what lifetimes are unused in async function.
 async fn async_wrong_without_args<'a>() {}
+//~^ ERROR lifetime parameter `'a` never used [unused_lifetimes]
 
 async fn async_wrong_1_lifetime<'a>(_: &i32) {}
+//~^ ERROR lifetime parameter `'a` never used [unused_lifetimes]
 
 async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
+//~^ ERROR lifetime parameter `'b` never used [unused_lifetimes]
 
 async fn async_right_1_lifetime<'a>(_: &'a i32) {}
 
diff --git a/src/test/ui/async-await/unused-lifetime.stderr b/src/test/ui/async-await/unused-lifetime.stderr
index 4e90f43fdd0..85304b9cb9e 100644
--- a/src/test/ui/async-await/unused-lifetime.stderr
+++ b/src/test/ui/async-await/unused-lifetime.stderr
@@ -1,8 +1,8 @@
 error: lifetime parameter `'a` never used
-  --> $DIR/unused-lifetime.rs:31:23
+  --> $DIR/unused-lifetime.rs:12:35
    |
-LL | fn wrong_without_args<'a>() {}
-   |                      -^^- help: elide the unused lifetime
+LL | async fn async_wrong_without_args<'a>() {}
+   |                                  -^^- help: elide the unused lifetime
    |
 note: the lint level is defined here
   --> $DIR/unused-lifetime.rs:5:9
@@ -11,18 +11,40 @@ LL | #![deny(unused_lifetimes)]
    |         ^^^^^^^^^^^^^^^^
 
 error: lifetime parameter `'a` never used
-  --> $DIR/unused-lifetime.rs:33:21
+  --> $DIR/unused-lifetime.rs:15:33
+   |
+LL | async fn async_wrong_1_lifetime<'a>(_: &i32) {}
+   |                                 ^^-----
+   |                                 |
+   |                                 help: elide the unused lifetime
+
+error: lifetime parameter `'b` never used
+  --> $DIR/unused-lifetime.rs:18:38
+   |
+LL | async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
+   |                                      ^^-----------------
+   |                                      |
+   |                                      help: elide the unused lifetime
+
+error: lifetime parameter `'a` never used
+  --> $DIR/unused-lifetime.rs:34:23
+   |
+LL | fn wrong_without_args<'a>() {}
+   |                      -^^- help: elide the unused lifetime
+
+error: lifetime parameter `'a` never used
+  --> $DIR/unused-lifetime.rs:36:21
    |
 LL | fn wrong_1_lifetime<'a>(_: &i32) {}
    |                    -^^- help: elide the unused lifetime
 
 error: lifetime parameter `'b` never used
-  --> $DIR/unused-lifetime.rs:35:26
+  --> $DIR/unused-lifetime.rs:38:26
    |
 LL | fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
    |                        --^^
    |                        |
    |                        help: elide the unused lifetime
 
-error: aborting due to 3 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/dropck/drop-with-active-borrows-2.stderr b/src/test/ui/dropck/drop-with-active-borrows-2.stderr
index 24650dfac02..d5b747d42fb 100644
--- a/src/test/ui/dropck/drop-with-active-borrows-2.stderr
+++ b/src/test/ui/dropck/drop-with-active-borrows-2.stderr
@@ -1,10 +1,9 @@
 error[E0515]: cannot return value referencing local variable `raw_lines`
-  --> $DIR/drop-with-active-borrows-2.rs:3:5
+  --> $DIR/drop-with-active-borrows-2.rs:3:30
    |
 LL |     raw_lines.iter().map(|l| l.trim()).collect()
-   |     ----------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ----------------         ^^^^^^^^ returns a value referencing data owned by the current function
    |     |
-   |     returns a value referencing data owned by the current function
    |     `raw_lines` is borrowed here
 
 error: aborting due to previous error
diff --git a/src/test/ui/issues/issue-13497-2.rs b/src/test/ui/issues/issue-13497-2.rs
index c82da0f0096..32abe2b8543 100644
--- a/src/test/ui/issues/issue-13497-2.rs
+++ b/src/test/ui/issues/issue-13497-2.rs
@@ -1,7 +1,7 @@
 fn read_lines_borrowed<'a>() -> Vec<&'a str> {
     let rawLines: Vec<String> = vec!["foo  ".to_string(), "  bar".to_string()];
-    rawLines //~ ERROR cannot return value referencing local variable `rawLines`
-        .iter().map(|l| l.trim()).collect()
+    rawLines.iter().map(|l| l.trim()).collect()
+    //~^ ERROR cannot return value referencing local variable `rawLines`
 }
 
 fn main() {}
diff --git a/src/test/ui/issues/issue-13497-2.stderr b/src/test/ui/issues/issue-13497-2.stderr
index 6f72b79f2a5..1b78e7ec1c6 100644
--- a/src/test/ui/issues/issue-13497-2.stderr
+++ b/src/test/ui/issues/issue-13497-2.stderr
@@ -1,14 +1,10 @@
 error[E0515]: cannot return value referencing local variable `rawLines`
-  --> $DIR/issue-13497-2.rs:3:5
+  --> $DIR/issue-13497-2.rs:3:29
    |
-LL |        rawLines
-   |   _____^
-   |  |_____|
-   | ||
-LL | ||         .iter().map(|l| l.trim()).collect()
-   | ||_______________-___________________________^ returns a value referencing data owned by the current function
-   | |________________|
-   |                  `rawLines` is borrowed here
+LL |     rawLines.iter().map(|l| l.trim()).collect()
+   |     ---------------         ^^^^^^^^ returns a value referencing data owned by the current function
+   |     |
+   |     `rawLines` is borrowed here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
index 57374b7e3bb..aaed3665149 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
@@ -20,9 +20,8 @@ error: lifetime may not live long enough
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
    |
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
-   |                  --              -                             ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
-   |                  |               |
-   |                  |               let's call the lifetime of this reference `'1`
+   |                  --  ---- has type `Pin<&'1 Foo>`              ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
+   |                  |
    |                  lifetime `'a` defined here
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
index 299a2d2f2d3..042ae53dba1 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
@@ -2,25 +2,25 @@ error[E0623]: lifetime mismatch
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
    |
 LL |     async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
-   |                                    ----     ----   ^ ...but data from `f` is returned here
+   |                          ----      ----            ^ ...but data from `f` flows into `self` here
    |                                    |
-   |                                    this parameter and the return type are declared with different lifetimes...
+   |                                    these two types are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:82
    |
 LL |     async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
-   |                                     ----              -----------------          ^ ...but data from `f` is returned here
+   |                          -----      ----                                         ^ ...but data from `f` flows into `self` here
    |                                     |
-   |                                     this parameter and the return type are declared with different lifetimes...
+   |                                     these two types are declared with different lifetimes...
 
 error[E0623]: lifetime mismatch
   --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
    |
 LL |     async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
-   |                                               ------     ---   ^^^ ...but data from `arg` is returned here
+   |                                  -----        ------           ^^^ ...but data from `arg` flows into `self` here
    |                                               |
-   |                                               this parameter and the return type are declared with different lifetimes...
+   |                                               these two types are declared with different lifetimes...
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr
index 7448e8484b4..ae484670213 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.stderr
@@ -2,61 +2,49 @@ error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:13:9
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
-   |                                 ----     ----
-   |                                 |
-   |                                 this parameter and the return type are declared with different lifetimes...
+   |                       -----     ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:19:9
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
-   |                                       ----     ----
-   |                                       |
-   |                                       this parameter and the return type are declared with different lifetimes...
+   |                             -----     ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:23:9
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
-   |                                                ----     ----
-   |                                                |
-   |                                                this parameter and the return type are declared with different lifetimes...
+   |                                     -----      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:27:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
-   |                                                ----     ----
-   |                                                |
-   |                                                this parameter and the return type are declared with different lifetimes...
+   |                                     -----      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:31:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
-   |                                                         ----     ----
-   |                                                         |
-   |                                                         this parameter and the return type are declared with different lifetimes...
+   |                                             -----       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/lt-ref-self-async.rs:35:9
    |
 LL |     async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
-   |                                                     ----     ----
-   |                                                     |
-   |                                                     this parameter and the return type are declared with different lifetimes...
+   |                                         -----       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr
index 6056cc46d3d..7b984b343d6 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.stderr
@@ -2,61 +2,49 @@ error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:13:9
    |
 LL |     async fn ref_self(&mut self, f: &u32) -> &u32 {
-   |                                     ----     ----
-   |                                     |
-   |                                     this parameter and the return type are declared with different lifetimes...
+   |                       ---------     ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:19:9
    |
 LL |     async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
-   |                                           ----     ----
-   |                                           |
-   |                                           this parameter and the return type are declared with different lifetimes...
+   |                             ---------     ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:23:9
    |
 LL |     async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
-   |                                                    ----     ----
-   |                                                    |
-   |                                                    this parameter and the return type are declared with different lifetimes...
+   |                                     ---------      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:27:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
-   |                                                    ----     ----
-   |                                                    |
-   |                                                    this parameter and the return type are declared with different lifetimes...
+   |                                     ---------      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:31:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
-   |                                                             ----     ----
-   |                                                             |
-   |                                                             this parameter and the return type are declared with different lifetimes...
+   |                                             ---------       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-self-async.rs:35:9
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
-   |                                                             ----     ----
-   |                                                             |
-   |                                                             this parameter and the return type are declared with different lifetimes...
+   |                                             ---------       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr
index 61034ae4d47..87a144f62f6 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr
@@ -2,51 +2,41 @@ error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:13:9
    |
 LL |     async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
-   |                                               ----     ----
-   |                                               |
-   |                                               this parameter and the return type are declared with different lifetimes...
+   |                               -----------     ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:17:9
    |
 LL |     async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
-   |                                                        ----     ----
-   |                                                        |
-   |                                                        this parameter and the return type are declared with different lifetimes...
+   |                                       -----------      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:21:9
    |
 LL |     async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
-   |                                                        ----     ----
-   |                                                        |
-   |                                                        this parameter and the return type are declared with different lifetimes...
+   |                                       -----------      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:25:9
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
-   |                                                                 ----     ----
-   |                                                                 |
-   |                                                                 this parameter and the return type are declared with different lifetimes...
+   |                                               -----------       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-mut-struct-async.rs:29:9
    |
 LL |     async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
-   |                                                                 ----     ----
-   |                                                                 |
-   |                                                                 this parameter and the return type are declared with different lifetimes...
+   |                                               -----------       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr
index 0eab16e685d..15c20c1bc4d 100644
--- a/src/test/ui/self/elision/ref-self-async.stderr
+++ b/src/test/ui/self/elision/ref-self-async.stderr
@@ -2,71 +2,57 @@ error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:23:9
    |
 LL |     async fn ref_self(&self, f: &u32) -> &u32 {
-   |                                 ----     ----
-   |                                 |
-   |                                 this parameter and the return type are declared with different lifetimes...
+   |                       -----     ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:29:9
    |
 LL |     async fn ref_Self(self: &Self, f: &u32) -> &u32 {
-   |                                       ----     ----
-   |                                       |
-   |                                       this parameter and the return type are declared with different lifetimes...
+   |                             -----     ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:33:9
    |
 LL |     async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
-   |                                                ----     ----
-   |                                                |
-   |                                                this parameter and the return type are declared with different lifetimes...
+   |                                     -----      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:37:9
    |
 LL |     async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
-   |                                                ----     ----
-   |                                                |
-   |                                                this parameter and the return type are declared with different lifetimes...
+   |                                     -----      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:41:9
    |
 LL |     async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
-   |                                                         ----     ----
-   |                                                         |
-   |                                                         this parameter and the return type are declared with different lifetimes...
+   |                                             -----       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:45:9
    |
 LL |     async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
-   |                                                         ----     ----
-   |                                                         |
-   |                                                         this parameter and the return type are declared with different lifetimes...
+   |                                             -----       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-self-async.rs:49:9
    |
 LL |     async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
-   |                                                             ---     ---
-   |                                                             |
-   |                                                             this parameter and the return type are declared with different lifetimes...
+   |                                            -----            --- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr
index aa1d7453e83..f24be3b58a7 100644
--- a/src/test/ui/self/elision/ref-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.stderr
@@ -2,51 +2,41 @@ error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:13:9
    |
 LL |     async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
-   |                                           ----     ----
-   |                                           |
-   |                                           this parameter and the return type are declared with different lifetimes...
+   |                               -------     ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:17:9
    |
 LL |     async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
-   |                                                    ----     ----
-   |                                                    |
-   |                                                    this parameter and the return type are declared with different lifetimes...
+   |                                       -------      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:21:9
    |
 LL |     async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
-   |                                                    ----     ----
-   |                                                    |
-   |                                                    this parameter and the return type are declared with different lifetimes...
+   |                                       -------      ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:25:9
    |
 LL |     async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
-   |                                                             ----     ----
-   |                                                             |
-   |                                                             this parameter and the return type are declared with different lifetimes...
+   |                                               -------       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error[E0623]: lifetime mismatch
   --> $DIR/ref-struct-async.rs:29:9
    |
 LL |     async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
-   |                                                         ----     ----
-   |                                                         |
-   |                                                         this parameter and the return type are declared with different lifetimes...
+   |                                           -------       ---- these two types are declared with different lifetimes...
 LL |         f
-   |         ^ ...but data from `f` is returned here
+   |         ^ ...but data from `f` flows into `self` here
 
 error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.fixed b/src/tools/clippy/tests/ui/manual_async_fn.fixed
index 136cc96be70..e9ca66f125d 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.fixed
+++ b/src/tools/clippy/tests/ui/manual_async_fn.fixed
@@ -80,6 +80,7 @@ fn elided_not_bound(_: &i32) -> impl Future<Output = i32> {
     async { 42 }
 }
 
+#[allow(clippy::needless_lifetimes)]
 async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }
 
 // should be ignored
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.rs b/src/tools/clippy/tests/ui/manual_async_fn.rs
index ddc453ffdb7..c3fa846485b 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.rs
+++ b/src/tools/clippy/tests/ui/manual_async_fn.rs
@@ -98,6 +98,7 @@ fn elided_not_bound(_: &i32) -> impl Future<Output = i32> {
     async { 42 }
 }
 
+#[allow(clippy::needless_lifetimes)]
 fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
     async { 42 }
 }
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.stderr b/src/tools/clippy/tests/ui/manual_async_fn.stderr
index 7435f46074c..b83abfccd4e 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.stderr
+++ b/src/tools/clippy/tests/ui/manual_async_fn.stderr
@@ -140,7 +140,7 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
    |                                                      ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> $DIR/manual_async_fn.rs:101:1
+  --> $DIR/manual_async_fn.rs:102:1
    |
 LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
index ffa152427a9..8df50d79ca5 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
@@ -19,6 +19,12 @@ LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
+  --> $DIR/needless_lifetimes.rs:37:1
+   |
+LL | async fn func<'a>(args: &[&'a str]) -> Option<&'a str> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration)
   --> $DIR/needless_lifetimes.rs:56:1
    |
 LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {
@@ -192,5 +198,5 @@ error: explicit lifetimes given in parameter types where they could be elided (o
 LL |         fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 32 previous errors
+error: aborting due to 33 previous errors