about summary refs log tree commit diff
diff options
context:
space:
mode:
authorllogiq <bogusandre@gmail.com>2024-12-08 16:00:54 +0000
committerGitHub <noreply@github.com>2024-12-08 16:00:54 +0000
commitc4aeb32f1dc0fcebf6b7ff789dee25c3faab1c5b (patch)
tree09eb70c4433ff6019366da7aec4fa19c4800bb64
parentec37eb60396c9288234ffffee130f96712f1703c (diff)
parentc963e22f05a77c0b7a959f987c048fbbb8865583 (diff)
downloadrust-c4aeb32f1dc0fcebf6b7ff789dee25c3faab1c5b.tar.gz
rust-c4aeb32f1dc0fcebf6b7ff789dee25c3faab1c5b.zip
chore: use multipart_suggestions for manual_async_fn (#13788)
This addresses #13099 for the manual_async_fn test.

changelog: [manual_async_fn]: Updated manual_async_fn to use
multipart_suggestions where appropriate
-rw-r--r--clippy_lints/src/manual_async_fn.rs21
-rw-r--r--tests/ui/manual_async_fn.fixed116
-rw-r--r--tests/ui/manual_async_fn.rs3
-rw-r--r--tests/ui/manual_async_fn.stderr134
4 files changed, 166 insertions, 108 deletions
diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs
index 3c77db84a40..9f3b0957eab 100644
--- a/clippy_lints/src/manual_async_fn.rs
+++ b/clippy_lints/src/manual_async_fn.rs
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
                     if let Some(vis_snip) = vis_span.get_source_text(cx)
                         && let Some(header_snip) = header_span.get_source_text(cx)
                         && let Some(ret_pos) = position_before_rarrow(&header_snip)
-                        && let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output)
+                        && let Some((_, ret_snip)) = suggested_ret(cx, output)
                     {
                         let header_snip = if vis_snip.is_empty() {
                             format!("async {}", &header_snip[..ret_pos])
@@ -82,19 +82,14 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
                             format!("{} async {}", vis_snip, &header_snip[vis_snip.len() + 1..ret_pos])
                         };
 
-                        let help = format!("make the function `async` and {ret_sugg}");
-                        diag.span_suggestion(
-                            header_span,
-                            help,
-                            format!("{header_snip}{ret_snip}"),
-                            Applicability::MachineApplicable,
-                        );
+                        let body_snip = snippet_block(cx, closure_body.value.span, "..", Some(block.span)).to_string();
 
-                        let body_snip = snippet_block(cx, closure_body.value.span, "..", Some(block.span));
-                        diag.span_suggestion(
-                            block.span,
-                            "move the body of the async block to the enclosing function",
-                            body_snip,
+                        diag.multipart_suggestion(
+                            "make the function `async` and return the output of the future directly",
+                            vec![
+                                (header_span, format!("{header_snip}{ret_snip}")),
+                                (block.span, body_snip),
+                            ],
                             Applicability::MachineApplicable,
                         );
                     }
diff --git a/tests/ui/manual_async_fn.fixed b/tests/ui/manual_async_fn.fixed
new file mode 100644
index 00000000000..dc1cb8e11fc
--- /dev/null
+++ b/tests/ui/manual_async_fn.fixed
@@ -0,0 +1,116 @@
+#![warn(clippy::manual_async_fn)]
+#![allow(clippy::needless_pub_self, unused)]
+
+use std::future::Future;
+
+async fn fut() -> i32 { 42 }
+
+#[rustfmt::skip]
+async fn fut2() -> i32 { 42 }
+
+#[rustfmt::skip]
+async fn fut3() -> i32 { 42 }
+
+async fn empty_fut() {}
+
+#[rustfmt::skip]
+async fn empty_fut2() {}
+
+#[rustfmt::skip]
+async fn empty_fut3() {}
+
+async fn core_fut() -> i32 { 42 }
+
+// should be ignored
+fn has_other_stmts() -> impl core::future::Future<Output = i32> {
+    let _ = 42;
+    async move { 42 }
+}
+
+// should be ignored
+fn not_fut() -> i32 {
+    42
+}
+
+// should be ignored
+async fn already_async() -> impl Future<Output = i32> {
+    async { 42 }
+}
+
+struct S;
+impl S {
+    async fn inh_fut() -> i32 {
+        // NOTE: this code is here just to check that the indentation is correct in the suggested fix
+        let a = 42;
+        let b = 21;
+        if a < b {
+            let c = 21;
+            let d = 42;
+            if c < d {
+                let _ = 42;
+            }
+        }
+        42
+    }
+
+    // should be ignored
+    fn not_fut(&self) -> i32 {
+        42
+    }
+
+    // should be ignored
+    fn has_other_stmts() -> impl core::future::Future<Output = i32> {
+        let _ = 42;
+        async move { 42 }
+    }
+
+    // should be ignored
+    async fn already_async(&self) -> impl Future<Output = i32> {
+        async { 42 }
+    }
+}
+
+// Tests related to lifetime capture
+
+async fn elided(_: &i32) -> i32 { 42 }
+
+// should be ignored
+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
+#[allow(clippy::needless_lifetimes)]
+fn explicit_not_bound<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> {
+    async { 42 }
+}
+
+// should be ignored
+mod issue_5765 {
+    use std::future::Future;
+
+    struct A;
+    impl A {
+        fn f(&self) -> impl Future<Output = ()> {
+            async {}
+        }
+    }
+
+    fn test() {
+        let _future = {
+            let a = A;
+            a.f()
+        };
+    }
+}
+
+pub async fn issue_10450() -> i32 { 42 }
+
+pub(crate) async fn issue_10450_2() -> i32 { 42 }
+
+pub(self) async fn issue_10450_3() -> i32 { 42 }
+
+fn main() {}
diff --git a/tests/ui/manual_async_fn.rs b/tests/ui/manual_async_fn.rs
index 6b8ac5033a9..9ca7654a368 100644
--- a/tests/ui/manual_async_fn.rs
+++ b/tests/ui/manual_async_fn.rs
@@ -1,8 +1,6 @@
 #![warn(clippy::manual_async_fn)]
 #![allow(clippy::needless_pub_self, unused)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 use std::future::Future;
 
 fn fut() -> impl Future<Output = i32> {
@@ -99,6 +97,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/tests/ui/manual_async_fn.stderr b/tests/ui/manual_async_fn.stderr
index f88fc30b3b5..68a97243436 100644
--- a/tests/ui/manual_async_fn.stderr
+++ b/tests/ui/manual_async_fn.stderr
@@ -1,5 +1,5 @@
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:8:1
+  --> tests/ui/manual_async_fn.rs:6:1
    |
 LL | fn fut() -> impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,116 +8,84 @@ LL | fn fut() -> impl Future<Output = i32> {
    = help: to override `-D warnings` add `#[allow(clippy::manual_async_fn)]`
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn fut() -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn fut() -> impl Future<Output = i32> { 42 }
-   |                                       ~~~~~~
+LL | async fn fut() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:13:1
+  --> tests/ui/manual_async_fn.rs:11:1
    |
 LL | fn fut2() ->impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn fut2() -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn fut2() ->impl Future<Output = i32> { 42 }
-   |                                       ~~~~~~
+LL | async fn fut2() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:18:1
+  --> tests/ui/manual_async_fn.rs:16:1
    |
 LL | fn fut3()-> impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn fut3() -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn fut3()-> impl Future<Output = i32> { 42 }
-   |                                       ~~~~~~
+LL | async fn fut3() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:22:1
+  --> tests/ui/manual_async_fn.rs:20:1
    |
 LL | fn empty_fut() -> impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: make the function `async` and remove the return type
-   |
-LL | async fn empty_fut() {
-   | ~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
+help: make the function `async` and return the output of the future directly
    |
-LL | fn empty_fut() -> impl Future<Output = ()> {}
-   |                                            ~~
+LL | async fn empty_fut() {}
+   | ~~~~~~~~~~~~~~~~~~~~ ~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:27:1
+  --> tests/ui/manual_async_fn.rs:25:1
    |
 LL | fn empty_fut2() ->impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: make the function `async` and remove the return type
-   |
-LL | async fn empty_fut2() {
-   | ~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
+help: make the function `async` and return the output of the future directly
    |
-LL | fn empty_fut2() ->impl Future<Output = ()> {}
-   |                                            ~~
+LL | async fn empty_fut2() {}
+   | ~~~~~~~~~~~~~~~~~~~~~ ~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:32:1
+  --> tests/ui/manual_async_fn.rs:30:1
    |
 LL | fn empty_fut3()-> impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: make the function `async` and remove the return type
-   |
-LL | async fn empty_fut3() {
-   | ~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
+help: make the function `async` and return the output of the future directly
    |
-LL | fn empty_fut3()-> impl Future<Output = ()> {}
-   |                                            ~~
+LL | async fn empty_fut3() {}
+   | ~~~~~~~~~~~~~~~~~~~~~ ~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:36:1
+  --> tests/ui/manual_async_fn.rs:34:1
    |
 LL | fn core_fut() -> impl core::future::Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn core_fut() -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
-   |                                                          ~~~~~~
+LL | async fn core_fut() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:58:5
+  --> tests/ui/manual_async_fn.rs:56:5
    |
 LL |     fn inh_fut() -> impl Future<Output = i32> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL |     async fn inh_fut() -> i32 {
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL ~     fn inh_fut() -> impl Future<Output = i32> {
+LL ~     async fn inh_fut() -> i32 {
 LL +         // NOTE: this code is here just to check that the indentation is correct in the suggested fix
 LL +         let a = 42;
 LL +         let b = 21;
@@ -133,79 +101,59 @@ LL +     }
    |
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:93:1
+  --> tests/ui/manual_async_fn.rs:91:1
    |
 LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn elided(_: &i32) -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
-   |                                                      ~~~~~~
+LL | async fn elided(_: &i32) -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:102:1
+  --> tests/ui/manual_async_fn.rs:101:1
    |
 LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b { 42 }
-   |                                                                                    ~~~~~~
+LL | async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:131:1
+  --> tests/ui/manual_async_fn.rs:130:1
    |
 LL | pub fn issue_10450() -> impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | pub async fn issue_10450() -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | pub fn issue_10450() -> impl Future<Output = i32> { 42 }
-   |                                                   ~~~~~~
+LL | pub async fn issue_10450() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:135:1
+  --> tests/ui/manual_async_fn.rs:134:1
    |
 LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | pub(crate) async fn issue_10450_2() -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> { 42 }
-   |                                                            ~~~~~~
+LL | pub(crate) async fn issue_10450_2() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:139:1
+  --> tests/ui/manual_async_fn.rs:138:1
    |
 LL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | pub(self) async fn issue_10450_3() -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> { 42 }
-   |                                                           ~~~~~~
+LL | pub(self) async fn issue_10450_3() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: aborting due to 13 previous errors