diff options
| author | bors <bors@rust-lang.org> | 2023-11-28 20:27:48 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-11-28 20:27:48 +0000 |
| commit | 57397a5190ba1b7a5a241ead090702b56959b025 (patch) | |
| tree | b3b04ec368dd5b26414f68200415f5f5f553ebba | |
| parent | 91c5653a474a0a81249f8146004b35c710e40f9b (diff) | |
| parent | 0426913ca95d457abefb192cde878d9eaab4b8a0 (diff) | |
| download | rust-57397a5190ba1b7a5a241ead090702b56959b025.tar.gz rust-57397a5190ba1b7a5a241ead090702b56959b025.zip | |
Auto merge of #11363 - KisaragiEffective:fix_redundant_closure_call_on_closure_returns_async_block, r=llogiq
[`redundant_closure_call`]: avoid duplicated `async` keyword when triggering on closure that returns `async` block close #11357 ---- *Please write a short comment explaining your change (or "none" for internal only changes)* changelog: [`redundant_closure_call`]: avoid duplicated `async` keyword when triggering on closure that returns `async` block
| -rw-r--r-- | clippy_lints/src/redundant_closure_call.rs | 35 | ||||
| -rw-r--r-- | tests/ui/redundant_closure_call_fixable.fixed | 18 | ||||
| -rw-r--r-- | tests/ui/redundant_closure_call_fixable.rs | 18 | ||||
| -rw-r--r-- | tests/ui/redundant_closure_call_fixable.stderr | 20 |
4 files changed, 77 insertions, 14 deletions
diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs index 7971a5d86e3..8bac2e40e01 100644 --- a/clippy_lints/src/redundant_closure_call.rs +++ b/clippy_lints/src/redundant_closure_call.rs @@ -4,8 +4,8 @@ use clippy_utils::get_parent_expr; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_hir::intravisit as hir_visit; use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor}; +use rustc_hir::{intravisit as hir_visit, CoroutineKind, CoroutineSource, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::hir::nested_filter; use rustc_middle::lint::in_external_macro; @@ -60,11 +60,14 @@ impl<'tcx> Visitor<'tcx> for ReturnVisitor { } } -/// Checks if the body is owned by an async closure -fn is_async_closure(body: &hir::Body<'_>) -> bool { - if let hir::ExprKind::Closure(closure) = body.value.kind - && let [resume_ty] = closure.fn_decl.inputs - && let hir::TyKind::Path(hir::QPath::LangItem(hir::LangItem::ResumeTy, ..)) = resume_ty.kind +/// Checks if the body is owned by an async closure. +/// Returns true for `async || whatever_expression`, but false for `|| async { whatever_expression +/// }`. +fn is_async_closure(cx: &LateContext<'_>, body: &hir::Body<'_>) -> bool { + if let hir::ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind + && let desugared_inner_closure_body = cx.tcx.hir().body(innermost_closure_generated_by_desugar.body) + // checks whether it is `async || whatever_expression` + && let Some(CoroutineKind::Async(CoroutineSource::Closure)) = desugared_inner_closure_body.coroutine_kind { true } else { @@ -100,7 +103,7 @@ fn find_innermost_closure<'tcx>( data = Some(( body.value, closure.fn_decl, - if is_async_closure(body) { + if is_async_closure(cx, body) { ty::Asyncness::Yes } else { ty::Asyncness::No @@ -173,12 +176,18 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { hint = hint.asyncify(); } - diag.span_suggestion( - full_expr.span, - "try doing something like", - hint.maybe_par(), - applicability, - ); + let is_in_fn_call_arg = + clippy_utils::get_parent_node(cx.tcx, expr.hir_id).is_some_and(|x| match x { + Node::Expr(expr) => matches!(expr.kind, hir::ExprKind::Call(_, _)), + _ => false, + }); + + // avoid clippy::double_parens + if !is_in_fn_call_arg { + hint = hint.maybe_par(); + }; + + diag.span_suggestion(full_expr.span, "try doing something like", hint, applicability); } }, ); diff --git a/tests/ui/redundant_closure_call_fixable.fixed b/tests/ui/redundant_closure_call_fixable.fixed index bf268d0b583..f272d8359a3 100644 --- a/tests/ui/redundant_closure_call_fixable.fixed +++ b/tests/ui/redundant_closure_call_fixable.fixed @@ -84,3 +84,21 @@ fn issue9956() { bar()(42, 5); foo(42, 5); } + +async fn issue11357() { + async {}.await; +} + +mod issue11707 { + use core::future::Future; + + fn spawn_on(fut: impl Future<Output = ()>) {} + + fn demo() { + spawn_on(async move {}); + } +} + +fn avoid_double_parens() { + std::convert::identity(13_i32 + 36_i32).leading_zeros(); +} diff --git a/tests/ui/redundant_closure_call_fixable.rs b/tests/ui/redundant_closure_call_fixable.rs index c8a91049d19..f45db8c9cff 100644 --- a/tests/ui/redundant_closure_call_fixable.rs +++ b/tests/ui/redundant_closure_call_fixable.rs @@ -84,3 +84,21 @@ fn issue9956() { bar()((|| || 42)()(), 5); foo((|| || 42)()(), 5); } + +async fn issue11357() { + (|| async {})().await; +} + +mod issue11707 { + use core::future::Future; + + fn spawn_on(fut: impl Future<Output = ()>) {} + + fn demo() { + spawn_on((|| async move {})()); + } +} + +fn avoid_double_parens() { + std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros(); +} diff --git a/tests/ui/redundant_closure_call_fixable.stderr b/tests/ui/redundant_closure_call_fixable.stderr index a7cdb43693f..028d383ad35 100644 --- a/tests/ui/redundant_closure_call_fixable.stderr +++ b/tests/ui/redundant_closure_call_fixable.stderr @@ -123,5 +123,23 @@ error: try not to call a closure in the expression where it is declared LL | foo((|| || 42)()(), 5); | ^^^^^^^^^^^^^^ help: try doing something like: `42` -error: aborting due to 14 previous errors +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:89:5 + | +LL | (|| async {})().await; + | ^^^^^^^^^^^^^^^ help: try doing something like: `async {}` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:98:18 + | +LL | spawn_on((|| async move {})()); + | ^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async move {}` + +error: try not to call a closure in the expression where it is declared + --> $DIR/redundant_closure_call_fixable.rs:103:28 + | +LL | std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros(); + | ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32` + +error: aborting due to 17 previous errors |
