about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/shadow.rs15
-rw-r--r--tests/ui/shadow.rs15
2 files changed, 29 insertions, 1 deletions
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs
index ee282ee1dfb..10e03ac19bd 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() {}