about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryukang <moorekang@gmail.com>2023-08-02 16:17:31 +0800
committeryukang <moorekang@gmail.com>2023-08-02 16:32:49 +0800
commitac25636a8f1efa40d368eaec363b01b748e193a1 (patch)
treef0c89cfae1e716e6da4f9d1af99c581ea55b24ba
parent75b9f53e47d8a9765bbd54372b94040debcf1eef (diff)
downloadrust-ac25636a8f1efa40d368eaec363b01b748e193a1.tar.gz
rust-ac25636a8f1efa40d368eaec363b01b748e193a1.zip
fix RedundantLocals clippy caused by async and await
-rw-r--r--compiler/rustc_middle/src/lint.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs16
2 files changed, 22 insertions, 3 deletions
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index 7cdfeb995ab..f62e406692a 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -463,3 +463,12 @@ pub fn in_external_macro(sess: &Session, span: Span) -> bool {
         ExpnKind::Macro { .. } => true, // definitely a plugin
     }
 }
+
+/// Return whether `span` is generated by `async` or `await`.
+pub fn is_from_async_await(span: Span) -> bool {
+    let expn_data = span.ctxt().outer_expn_data();
+    match expn_data.kind {
+        ExpnKind::Desugaring(DesugaringKind::Async | DesugaringKind::Await) => true,
+        _ => false,
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index 140ae837a17..896bd79b20b 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -2,9 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::ty::needs_ordered_drop;
 use rustc_hir::def::Res;
-use rustc_hir::{BindingAnnotation, ByRef, Expr, ExprKind, HirId, Local, Node, Pat, PatKind, QPath};
+use rustc_hir::{
+    BindingAnnotation, ByRef, Expr, ExprKind, HirId, Local, Node, Pat, PatKind, QPath,
+};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
+use rustc_middle::lint::{in_external_macro, is_from_async_await};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::Ident;
 
@@ -65,6 +67,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
             // the local is user-controlled
             if !in_external_macro(cx.sess(), local.span);
             if !is_from_proc_macro(cx, expr);
+            // Async function parameters are lowered into the closure body, so we can't lint them.
+            // see `lower_maybe_async_body` in `rust_ast_lowering`
+            if !is_from_async_await(local.span);
             then {
                 span_lint_and_help(
                     cx,
@@ -93,7 +98,12 @@ fn find_binding(pat: &Pat<'_>, name: Ident) -> Option<BindingAnnotation> {
 }
 
 /// Check if a rebinding of a local affects the code's drop behavior.
-fn affects_drop_behavior<'tcx>(cx: &LateContext<'tcx>, bind: HirId, rebind: HirId, rebind_expr: &Expr<'tcx>) -> bool {
+fn affects_drop_behavior<'tcx>(
+    cx: &LateContext<'tcx>,
+    bind: HirId,
+    rebind: HirId,
+    rebind_expr: &Expr<'tcx>,
+) -> bool {
     let hir = cx.tcx.hir();
 
     // the rebinding is in a different scope than the original binding