use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
-use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sugg::Sugg;
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_ast::visit as ast_visit;
if_chain! {
if let ast::ExprKind::Call(ref paren, _) = expr.kind;
if let ast::ExprKind::Paren(ref closure) = paren.kind;
- if let ast::ExprKind::Closure(_, _, _, _, ref decl, ref block, _) = closure.kind;
+ if let ast::ExprKind::Closure(_, _, ref r#async, _, ref decl, ref block, _) = closure.kind;
then {
let mut visitor = ReturnVisitor::new();
visitor.visit_expr(block);
"try not to call a closure in the expression where it is declared",
|diag| {
if decl.inputs.is_empty() {
- let mut app = Applicability::MachineApplicable;
- let hint =
- snippet_with_applicability(cx, block.span, "..", &mut app).into_owned();
- diag.span_suggestion(expr.span, "try doing something like", hint, app);
+ let app = Applicability::MachineApplicable;
+ let mut hint = Sugg::ast(cx, block, "..");
+
+ if r#async.is_async() {
+ // `async x` is a syntax error, so it becomes `async { x }`
+ if !matches!(block.kind, ast::ExprKind::Block(_, _)) {
+ hint = hint.blockify();
+ }
+
+ hint = hint.asyncify();
+ }
+
+ diag.span_suggestion(expr.span, "try doing something like", hint.to_string(), app);
}
},
);
Sugg::NonParen(Cow::Owned(format!("{{ {} }}", self)))
}
+ /// Convenience method to prefix the expression with the `async` keyword.
+ /// Can be used after `blockify` to create an async block.
+ pub fn asyncify(self) -> Sugg<'static> {
+ Sugg::NonParen(Cow::Owned(format!("async {}", self)))
+ }
+
/// Convenience method to create the `<lhs>..<rhs>` or `<lhs>...<rhs>`
/// suggestion.
pub fn range(self, end: &Self, limit: ast::RangeLimits) -> Sugg<'static> {
// run-rustfix
+#![feature(async_closure)]
#![warn(clippy::redundant_closure_call)]
#![allow(unused)]
+async fn something() -> u32 {
+ 21
+}
+
+async fn something_else() -> u32 {
+ 2
+}
+
fn main() {
let a = 42;
+ let b = async {
+ let x = something().await;
+ let y = something_else().await;
+ x * y
+ };
+ let c = {
+ let x = 21;
+ let y = 2;
+ x * y
+ };
+ let d = async { something().await };
}
// run-rustfix
+#![feature(async_closure)]
#![warn(clippy::redundant_closure_call)]
#![allow(unused)]
+async fn something() -> u32 {
+ 21
+}
+
+async fn something_else() -> u32 {
+ 2
+}
+
fn main() {
let a = (|| 42)();
+ let b = (async || {
+ let x = something().await;
+ let y = something_else().await;
+ x * y
+ })();
+ let c = (|| {
+ let x = 21;
+ let y = 2;
+ x * y
+ })();
+ let d = (async || something().await)();
}
error: try not to call a closure in the expression where it is declared
- --> $DIR/redundant_closure_call_fixable.rs:7:13
+ --> $DIR/redundant_closure_call_fixable.rs:16:13
|
LL | let a = (|| 42)();
| ^^^^^^^^^ help: try doing something like: `42`
|
= note: `-D clippy::redundant-closure-call` implied by `-D warnings`
-error: aborting due to previous error
+error: try not to call a closure in the expression where it is declared
+ --> $DIR/redundant_closure_call_fixable.rs:17:13
+ |
+LL | let b = (async || {
+ | _____________^
+LL | | let x = something().await;
+LL | | let y = something_else().await;
+LL | | x * y
+LL | | })();
+ | |________^
+ |
+help: try doing something like
+ |
+LL ~ let b = async {
+LL + let x = something().await;
+LL + let y = something_else().await;
+LL + x * y
+LL ~ };
+ |
+
+error: try not to call a closure in the expression where it is declared
+ --> $DIR/redundant_closure_call_fixable.rs:22:13
+ |
+LL | let c = (|| {
+ | _____________^
+LL | | let x = 21;
+LL | | let y = 2;
+LL | | x * y
+LL | | })();
+ | |________^
+ |
+help: try doing something like
+ |
+LL ~ let c = {
+LL + let x = 21;
+LL + let y = 2;
+LL + x * y
+LL ~ };
+ |
+
+error: try not to call a closure in the expression where it is declared
+ --> $DIR/redundant_closure_call_fixable.rs:27:13
+ |
+LL | let d = (async || something().await)();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }`
+
+error: aborting due to 4 previous errors