about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-06-20 13:10:52 +0000
committerbors <bors@rust-lang.org>2022-06-20 13:10:52 +0000
commit97d451397de3f97fa586297a7bc2d16908d3d842 (patch)
tree7b9c1b532ffda0dddea766c764e6d0a90bfd1468
parent195f2cba458f0dcdce16b2d22212ec148a6126f5 (diff)
parenta0b107bbb624ab4bf889f916707d2f025964d3be (diff)
downloadrust-97d451397de3f97fa586297a7bc2d16908d3d842.tar.gz
rust-97d451397de3f97fa586297a7bc2d16908d3d842.zip
Auto merge of #9025 - Alexendoo:unused-async-method, r=dswij
unused_async: lint async methods

Now lints:

```rust
impl Foo {
    async fn method(&self) -> &'static str {
        "no await here"
    }
}
```

changelog: [`unused_async`]: lint async methods

Fixes #9024
-rw-r--r--clippy_lints/src/unused_async.rs28
-rw-r--r--tests/ui/methods.rs1
-rw-r--r--tests/ui/methods.stderr4
-rw-r--r--tests/ui/should_impl_trait/corner_cases.rs3
-rw-r--r--tests/ui/unused_async.rs34
-rw-r--r--tests/ui/unused_async.stderr14
6 files changed, 64 insertions, 20 deletions
diff --git a/clippy_lints/src/unused_async.rs b/clippy_lints/src/unused_async.rs
index c8ec4442ab1..a832dfcccaf 100644
--- a/clippy_lints/src/unused_async.rs
+++ b/clippy_lints/src/unused_async.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
-use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnHeader, HirId, IsAsync, YieldSource};
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, IsAsync, YieldSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -68,20 +68,18 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
         span: Span,
         hir_id: HirId,
     ) {
-        if let FnKind::ItemFn(_, _, FnHeader { asyncness, .. }) = &fn_kind {
-            if matches!(asyncness, IsAsync::Async) {
-                let mut visitor = AsyncFnVisitor { cx, found_await: false };
-                walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), span, hir_id);
-                if !visitor.found_await {
-                    span_lint_and_help(
-                        cx,
-                        UNUSED_ASYNC,
-                        span,
-                        "unused `async` for function with no await statements",
-                        None,
-                        "consider removing the `async` from this function",
-                    );
-                }
+        if !span.from_expansion() && fn_kind.asyncness() == IsAsync::Async {
+            let mut visitor = AsyncFnVisitor { cx, found_await: false };
+            walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), span, hir_id);
+            if !visitor.found_await {
+                span_lint_and_help(
+                    cx,
+                    UNUSED_ASYNC,
+                    span,
+                    "unused `async` for function with no await statements",
+                    None,
+                    "consider removing the `async` from this function",
+                );
             }
         }
     }
diff --git a/tests/ui/methods.rs b/tests/ui/methods.rs
index 9805097084d..1970c2eae53 100644
--- a/tests/ui/methods.rs
+++ b/tests/ui/methods.rs
@@ -15,6 +15,7 @@
     clippy::use_self,
     clippy::useless_format,
     clippy::wrong_self_convention,
+    clippy::unused_async,
     clippy::unused_self,
     unused
 )]
diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr
index 6be38b24fbd..b63672dd6fd 100644
--- a/tests/ui/methods.stderr
+++ b/tests/ui/methods.stderr
@@ -1,5 +1,5 @@
 error: methods called `new` usually return `Self`
-  --> $DIR/methods.rs:103:5
+  --> $DIR/methods.rs:104:5
    |
 LL | /     fn new() -> i32 {
 LL | |         0
@@ -9,7 +9,7 @@ LL | |     }
    = note: `-D clippy::new-ret-no-self` implied by `-D warnings`
 
 error: called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling `.find(..)` instead
-  --> $DIR/methods.rs:124:13
+  --> $DIR/methods.rs:125:13
    |
 LL |       let _ = v.iter().filter(|&x| {
    |  _____________^
diff --git a/tests/ui/should_impl_trait/corner_cases.rs b/tests/ui/should_impl_trait/corner_cases.rs
index 1ccb0a1d167..50999c6f219 100644
--- a/tests/ui/should_impl_trait/corner_cases.rs
+++ b/tests/ui/should_impl_trait/corner_cases.rs
@@ -8,7 +8,8 @@
     clippy::missing_safety_doc,
     clippy::wrong_self_convention,
     clippy::missing_panics_doc,
-    clippy::return_self_not_must_use
+    clippy::return_self_not_must_use,
+    clippy::unused_async
 )]
 
 use std::ops::Mul;
diff --git a/tests/ui/unused_async.rs b/tests/ui/unused_async.rs
index 2a3a506a57b..4ca7f29b34c 100644
--- a/tests/ui/unused_async.rs
+++ b/tests/ui/unused_async.rs
@@ -1,5 +1,8 @@
 #![warn(clippy::unused_async)]
 
+use std::future::Future;
+use std::pin::Pin;
+
 async fn foo() -> i32 {
     4
 }
@@ -8,6 +11,37 @@ async fn bar() -> i32 {
     foo().await
 }
 
+struct S;
+
+impl S {
+    async fn unused(&self) -> i32 {
+        1
+    }
+
+    async fn used(&self) -> i32 {
+        self.unused().await
+    }
+}
+
+trait AsyncTrait {
+    fn trait_method() -> Pin<Box<dyn Future<Output = i32>>>;
+}
+
+macro_rules! async_trait_impl {
+    () => {
+        impl AsyncTrait for S {
+            fn trait_method() -> Pin<Box<dyn Future<Output = i32>>> {
+                async fn unused() -> i32 {
+                    5
+                }
+
+                Box::pin(unused())
+            }
+        }
+    };
+}
+async_trait_impl!();
+
 fn main() {
     foo();
     bar();
diff --git a/tests/ui/unused_async.stderr b/tests/ui/unused_async.stderr
index cc6096d65d9..8b8ad065a4c 100644
--- a/tests/ui/unused_async.stderr
+++ b/tests/ui/unused_async.stderr
@@ -1,5 +1,5 @@
 error: unused `async` for function with no await statements
-  --> $DIR/unused_async.rs:3:1
+  --> $DIR/unused_async.rs:6:1
    |
 LL | / async fn foo() -> i32 {
 LL | |     4
@@ -9,5 +9,15 @@ LL | | }
    = note: `-D clippy::unused-async` implied by `-D warnings`
    = help: consider removing the `async` from this function
 
-error: aborting due to previous error
+error: unused `async` for function with no await statements
+  --> $DIR/unused_async.rs:17:5
+   |
+LL | /     async fn unused(&self) -> i32 {
+LL | |         1
+LL | |     }
+   | |_____^
+   |
+   = help: consider removing the `async` from this function
+
+error: aborting due to 2 previous errors