Skip to content

Commit 03114bb

Browse files
committed
Fixes #7915
Fix shadow_same's positive false for async function's params: Example Code: ```rust #![deny(clippy::shadow_same)] pub async fn foo(_a: i32) { } ``` Output: ``` error: `_a` is shadowed by itself in `_a ``` Hir: ```rust pub async fn foo(_a: i32) -> /*impl Trait*/ #[lang = "from_generator"](move |mut _task_context| { let _a = _a; { let _t = { }; _t } }) ``` Skip checking async function's params. changelog: Fix shadow_same's positive false for async function's params
1 parent bb58dc8 commit 03114bb

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

clippy_lints/src/shadow.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use clippy_utils::diagnostics::span_lint_and_note;
22
use clippy_utils::source::snippet;
33
use clippy_utils::visitors::is_local_used;
4-
use rustc_data_structures::fx::FxHashMap;
4+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
55
use rustc_hir::def::Res;
66
use rustc_hir::def_id::LocalDefId;
77
use rustc_hir::hir_id::ItemLocalId;
8-
use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, Node, Pat, PatKind, QPath, UnOp};
8+
use rustc_hir::intravisit::FnKind;
9+
use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, FnDecl, HirId, IsAsync, Node, Pat, PatKind, QPath, UnOp};
910
use rustc_lint::{LateContext, LateLintPass};
1011
use rustc_session::{declare_tool_lint, impl_lint_pass};
1112
use rustc_span::{Span, Symbol};
@@ -95,6 +96,7 @@ declare_clippy_lint! {
9596
#[derive(Default)]
9697
pub(crate) struct Shadow {
9798
bindings: Vec<FxHashMap<Symbol, Vec<ItemLocalId>>>,
99+
skip: Vec<FxHashSet<Symbol>>,
98100
}
99101

100102
impl_lint_pass!(Shadow => [SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED]);
@@ -121,6 +123,11 @@ impl<'tcx> LateLintPass<'tcx> for Shadow {
121123
return;
122124
}
123125

126+
if self.skip.len() > 0 && self.skip.last_mut().unwrap().contains(&ident.name) {
127+
// skip async function's params
128+
return;
129+
}
130+
124131
if is_shadow(cx, owner, prev, local_id) {
125132
let prev_hir_id = HirId { owner, local_id: prev };
126133
lint_shadow(cx, pat, prev_hir_id, ident.span);
@@ -145,6 +152,58 @@ impl<'tcx> LateLintPass<'tcx> for Shadow {
145152
self.bindings.pop();
146153
}
147154
}
155+
156+
fn check_fn(
157+
&mut self,
158+
_: &LateContext<'tcx>,
159+
kind: FnKind<'tcx>,
160+
_: &'tcx FnDecl<'_>,
161+
body: &'tcx Body<'_>,
162+
_: Span,
163+
_: HirId,
164+
) {
165+
if_chain! {
166+
if let Some(header) = match kind {
167+
FnKind::ItemFn(_, _, header, _) => Some(header),
168+
FnKind::Method(_, sig, _) => Some(sig.header),
169+
_ => None,
170+
};
171+
if header.asyncness == IsAsync::Async;
172+
if body.params.len() > 0;
173+
then {
174+
self.skip.push(FxHashSet::default());
175+
let skip_params = self.skip.last_mut().unwrap();
176+
for i in body.params {
177+
if let PatKind::Binding(.., ident, _) = i.pat.kind {
178+
skip_params.insert(ident.name);
179+
}
180+
}
181+
}
182+
}
183+
}
184+
185+
fn check_fn_post(
186+
&mut self,
187+
_: &LateContext<'tcx>,
188+
kind: FnKind<'tcx>,
189+
_: &'tcx FnDecl<'_>,
190+
body: &'tcx Body<'_>,
191+
_: Span,
192+
_: HirId,
193+
) {
194+
if_chain! {
195+
if let Some(header) = match kind {
196+
FnKind::ItemFn(_, _, header, _) => Some(header),
197+
FnKind::Method(_, sig, _) => Some(sig.header),
198+
_ => None,
199+
};
200+
if header.asyncness == IsAsync::Async;
201+
if body.params.len() > 0;
202+
then {
203+
self.skip.pop();
204+
}
205+
}
206+
}
148207
}
149208

150209
fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {

tests/ui/shadow.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,10 @@ fn question_mark() -> Option<()> {
7979
None
8080
}
8181

82+
pub async fn foo1(_a: i32) {}
83+
84+
pub async fn foo2(_a: i32, _b: i64) {
85+
let _b = _a;
86+
}
87+
8288
fn main() {}

0 commit comments

Comments
 (0)