diff options
| author | Samuel Tardieu <sam@rfc1149.net> | 2025-03-27 11:59:27 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-27 11:59:27 +0000 |
| commit | a895265a4e44666c2c30de27f010c6467130c6e8 (patch) | |
| tree | b9c44263da0b0d4ec7131d185803e504d7b0c32b | |
| parent | 764c1b6d16c1830929469d3cf4307cd94789317c (diff) | |
| parent | d9913dd6ad07f113aa83b835da8253bdca4342a9 (diff) | |
| download | rust-a895265a4e44666c2c30de27f010c6467130c6e8.tar.gz rust-a895265a4e44666c2c30de27f010c6467130c6e8.zip | |
Do not warn about shadowing in a destructuring assigment (#14381)
When lowering a destructuring assignment from AST to HIR, the compiler will reuse the same identifier name (namely `sym::lhs`) for all the fields. The desugaring must be checked for to avoid a false positive of the `shadow_unrelated` lint. Fix #10279 Fix #14377 changelog: [`shadow_unrelated`]: prevent false positive in destructuring assignments
| -rw-r--r-- | clippy_lints/src/shadow.rs | 15 | ||||
| -rw-r--r-- | tests/ui/shadow.rs | 15 |
2 files changed, 29 insertions, 1 deletions
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 3795c7483da..91f29bc346b 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -8,7 +8,9 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; use rustc_hir::hir_id::ItemLocalId; -use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, LetExpr, Node, Pat, PatKind, QPath, UnOp}; +use rustc_hir::{ + Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, LetExpr, LocalSource, Node, Pat, PatKind, QPath, UnOp, +}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::{Span, Symbol}; @@ -125,6 +127,17 @@ impl<'tcx> LateLintPass<'tcx> for Shadow { return; } + // Desugaring of a destructuring assignment may reuse the same identifier internally. + // Peel `Pat` and `PatField` nodes and check if we reach a desugared `Let` assignment. + if let Some((_, Node::LetStmt(let_stmt))) = cx + .tcx + .hir_parent_iter(pat.hir_id) + .find(|(_, node)| !matches!(node, Node::Pat(_) | Node::PatField(_))) + && let LocalSource::AssignDesugar(_) = let_stmt.source + { + return; + } + let HirId { owner, local_id } = id; // get (or insert) the list of items for this owner and symbol let (ref mut data, scope_owner) = *self.bindings.last_mut().unwrap(); diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs index 7d503a1cf6c..05009b2ddd4 100644 --- a/tests/ui/shadow.rs +++ b/tests/ui/shadow.rs @@ -167,4 +167,19 @@ fn issue13795(value: Issue13795) { //~^ shadow_same } +fn issue14377() { + let a; + let b; + (a, b) = (0, 1); + + struct S { + c: i32, + d: i32, + } + + let c; + let d; + S { c, d } = S { c: 1, d: 2 }; +} + fn main() {} |
