Skip to content

Commit

Permalink
chore: use multipart_suggestions for manual_async_fn (#13788)
Browse files Browse the repository at this point in the history
This addresses #13099 for the manual_async_fn test.

changelog: [manual_async_fn]: Updated manual_async_fn to use
multipart_suggestions where appropriate
  • Loading branch information
llogiq authored Dec 8, 2024
2 parents ec37eb6 + c963e22 commit c4aeb32
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 108 deletions.
21 changes: 8 additions & 13 deletions clippy_lints/src/manual_async_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,27 +74,22 @@ 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])
} else {
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,
);
}
Expand Down
116 changes: 116 additions & 0 deletions tests/ui/manual_async_fn.fixed
Original file line number Diff line number Diff line change
@@ -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() {}
3 changes: 1 addition & 2 deletions tests/ui/manual_async_fn.rs
Original file line number Diff line number Diff line change
@@ -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> {
Expand Down Expand Up @@ -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 }
}
Expand Down
Loading

0 comments on commit c4aeb32

Please sign in to comment.