about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs20
-rw-r--r--src/test/ui/async-await/unused-lifetime.rs79
-rw-r--r--src/test/ui/async-await/unused-lifetime.stderr30
3 files changed, 65 insertions, 64 deletions
diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs
index cc0e99dc6b1..aab5c3cf8f5 100644
--- a/compiler/rustc_resolve/src/late/lifetimes.rs
+++ b/compiler/rustc_resolve/src/late/lifetimes.rs
@@ -644,17 +644,17 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                             } else {
                                 bug!();
                             };
-                            if let hir::ParamName::Plain(param_name) = name {
-                                if param_name.name == kw::UnderscoreLifetime {
-                                    // Pick the elided lifetime "definition" if one exists
-                                    // and use it to make an elision scope.
-                                    self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
-                                    elision = Some(reg);
-                                } else {
-                                    lifetimes.insert(name, reg);
-                                }
+                            // We cannot predict what lifetimes are unused in opaque type.
+                            self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
+                            if let hir::ParamName::Plain(Ident {
+                                name: kw::UnderscoreLifetime,
+                                ..
+                            }) = name
+                            {
+                                // Pick the elided lifetime "definition" if one exists
+                                // and use it to make an elision scope.
+                                elision = Some(reg);
                             } else {
-                                self.lifetime_uses.insert(def_id, LifetimeUseSet::Many);
                                 lifetimes.insert(name, reg);
                             }
                         }
diff --git a/src/test/ui/async-await/unused-lifetime.rs b/src/test/ui/async-await/unused-lifetime.rs
index 1cf546bcb42..5bd6ae8d3a4 100644
--- a/src/test/ui/async-await/unused-lifetime.rs
+++ b/src/test/ui/async-await/unused-lifetime.rs
@@ -1,42 +1,47 @@
-// edition:2018
+// Check "unused_lifetimes" lint on both async and sync functions
 
-// Avoid spurious warnings of unused lifetime. The below async functions
-// are desugered to have an unused lifetime
-// but we don't want to warn about that as there's nothing they can do about it.
+// edition:2018
 
 #![deny(unused_lifetimes)]
-#![allow(dead_code)]
-
-pub async fn october(s: &str) {
-    println!("{}", s);
-}
-
-pub async fn async_fn(&mut ref s: &mut[i32]) {
-    println!("{:?}", s);
-}
-
-macro_rules! foo_macro {
-    () => {
-        pub async fn async_fn_in_macro(&mut ref _s: &mut[i32]) {}
-    };
-}
-
-foo_macro!();
-
-pub async fn func_with_unused_lifetime<'a>(s: &'a str) {
-    //~^ ERROR lifetime parameter `'a` never used
-    println!("{}", s);
-}
-
-pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
-    //~^ ERROR lifetime parameter `'a` never used
-    //~^^ ERROR lifetime parameter `'b` never used
-    println!("{}", s);
-}
-
-pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) {
-    //~^ ERROR lifetime parameter `'c` never used
-    println!("{}", s);
-}
+
+
+// Async part with unused lifetimes
+//
+// 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>() {}
+
+async fn async_wrong_1_lifetime<'a>(_: &i32) {}
+
+async fn async_wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
+
+async fn async_right_1_lifetime<'a>(_: &'a i32) {}
+
+async fn async_right_2_lifetimes<'a, 'b>(_: &'a i32, _: &'b i32) {}
+
+async fn async_right_trait_bound_lifetime<'a, I>(_: I)
+where
+    I: Iterator<Item = &'a i32>
+{}
+
+
+// Sync part with unused lifetimes
+//
+// These functions are compiled as supposed
+fn wrong_without_args<'a>() {} //~ ERROR lifetime parameter `'a` never used
+
+fn wrong_1_lifetime<'a>(_: &i32) {} //~ ERROR lifetime parameter `'a` never used
+
+fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {} //~ ERROR lifetime parameter `'b` never used
+
+fn right_1_lifetime<'a>(_: &'a i32) {}
+
+fn right_2_lifetimes<'a, 'b>(_: &'a i32, _: &'b i32) {}
+
+fn right_trait_bound_lifetime<'a, I>(_: I)
+where
+    I: Iterator<Item = &'a i32>
+{}
+
 
 fn main() {}
diff --git a/src/test/ui/async-await/unused-lifetime.stderr b/src/test/ui/async-await/unused-lifetime.stderr
index 2a7a12a3643..4e90f43fdd0 100644
--- a/src/test/ui/async-await/unused-lifetime.stderr
+++ b/src/test/ui/async-await/unused-lifetime.stderr
@@ -1,32 +1,28 @@
 error: lifetime parameter `'a` never used
-  --> $DIR/unused-lifetime.rs:26:40
+  --> $DIR/unused-lifetime.rs:31:23
    |
-LL | pub async fn func_with_unused_lifetime<'a>(s: &'a str) {
-   |                                        ^^
+LL | fn wrong_without_args<'a>() {}
+   |                      -^^- help: elide the unused lifetime
    |
 note: the lint level is defined here
-  --> $DIR/unused-lifetime.rs:7:9
+  --> $DIR/unused-lifetime.rs:5:9
    |
 LL | #![deny(unused_lifetimes)]
    |         ^^^^^^^^^^^^^^^^
 
 error: lifetime parameter `'a` never used
-  --> $DIR/unused-lifetime.rs:31:44
+  --> $DIR/unused-lifetime.rs:33:21
    |
-LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
-   |                                            ^^
+LL | fn wrong_1_lifetime<'a>(_: &i32) {}
+   |                    -^^- help: elide the unused lifetime
 
 error: lifetime parameter `'b` never used
-  --> $DIR/unused-lifetime.rs:31:48
+  --> $DIR/unused-lifetime.rs:35:26
    |
-LL | pub async fn func_with_two_unused_lifetime<'a, 'b>(s: &'a str, t: &'b str) {
-   |                                                ^^
+LL | fn wrong_2_lifetimes<'a, 'b>(_: &'a i32, _: &i32) {}
+   |                        --^^
+   |                        |
+   |                        help: elide the unused lifetime
 
-error: lifetime parameter `'c` never used
-  --> $DIR/unused-lifetime.rs:37:54
-   |
-LL | pub async fn func_with_unused_lifetime_in_two_params<'c>(s: &'c str, t: &'c str) {
-   |                                                      ^^
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors