Skip to content

Commit

Permalink
Auto merge of rust-lang#10456 - samueltardieu:issue-10450, r=Manishearth
Browse files Browse the repository at this point in the history
Issue function modifiers in the right order in manual_async_fn lint

Fixes rust-lang#10450

changelog: [`manual_async_fn`] output function modifiers in correct order
  • Loading branch information
bors committed Mar 18, 2023
2 parents d3c8442 + afe27ba commit e64c596
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 4 deletions.
14 changes: 11 additions & 3 deletions clippy_lints/src/manual_async_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{
AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind, TypeBindingKind,
};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
Expand Down Expand Up @@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
decl: &'tcx FnDecl<'_>,
body: &'tcx Body<'_>,
span: Span,
_: LocalDefId,
def_id: LocalDefId,
) {
if_chain! {
if let Some(header) = kind.header();
Expand All @@ -60,6 +60,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
if let ExprKind::Block(block, _) = body.value.kind;
if block.stmts.is_empty();
if let Some(closure_body) = desugared_async_block(cx, block);
if let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) =
cx.tcx.hir().get_by_def_id(def_id);
then {
let header_span = span.with_hi(ret_ty.span.hi());

Expand All @@ -70,15 +72,21 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
"this function can be simplified using the `async fn` syntax",
|diag| {
if_chain! {
if let Some(vis_snip) = snippet_opt(cx, *vis_span);
if let Some(header_snip) = snippet_opt(cx, header_span);
if let Some(ret_pos) = position_before_rarrow(&header_snip);
if let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output);
then {
let header_snip = if !vis_snip.is_empty() {
format!("{} async {}", vis_snip, &header_snip[vis_snip.len() + 1..ret_pos])
} else {
format!("async {}", &header_snip[..ret_pos])
};
let help = format!("make the function `async` and {ret_sugg}");
diag.span_suggestion(
header_span,
help,
format!("async {}{ret_snip}", &header_snip[..ret_pos]),
format!("{header_snip}{ret_snip}"),
Applicability::MachineApplicable
);

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/manual_async_fn.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,10 @@ mod issue_5765 {
}
}

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() {}
12 changes: 12 additions & 0 deletions tests/ui/manual_async_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,16 @@ mod issue_5765 {
}
}

pub fn issue_10450() -> impl Future<Output = i32> {
async { 42 }
}

pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {
async { 42 }
}

pub(self) fn issue_10450_3() -> impl Future<Output = i32> {
async { 42 }
}

fn main() {}
47 changes: 46 additions & 1 deletion tests/ui/manual_async_fn.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,50 @@ 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 }
| ~~~~~~

error: aborting due to 10 previous errors
error: this function can be simplified using the `async fn` syntax
--> $DIR/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 }
| ~~~~~~

error: this function can be simplified using the `async fn` syntax
--> $DIR/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 }
| ~~~~~~

error: this function can be simplified using the `async fn` syntax
--> $DIR/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 }
| ~~~~~~

error: aborting due to 13 previous errors

0 comments on commit e64c596

Please sign in to comment.