]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/shadow.rs
Last PR adjustments
[rust.git] / clippy_lints / src / shadow.rs
index ce05c5a6164fd76ab6e88bf137de1fcb7bc0663e..87f966ced0df121b640a5b301809027ed3dd3cb3 100644 (file)
     /// ### Example
     /// ```rust
     /// # let x = 1;
-    /// // Bad
     /// let x = &x;
+    /// ```
     ///
-    /// // Good
+    /// Use instead:
+    /// ```rust
+    /// # let x = 1;
     /// let y = &x; // use different variable name
     /// ```
     #[clippy::version = "pre 1.29.0"]
     /// # let y = 1;
     /// # let z = 2;
     /// let x = y;
-    ///
-    /// // Bad
     /// let x = z; // shadows the earlier binding
+    /// ```
     ///
-    /// // Good
+    /// Use instead:
+    /// ```rust
+    /// # let y = 1;
+    /// # let z = 2;
+    /// let x = y;
     /// let w = z; // use different variable name
     /// ```
     #[clippy::version = "pre 1.29.0"]
 
 #[derive(Default)]
 pub(crate) struct Shadow {
-    bindings: Vec<FxHashMap<Symbol, Vec<ItemLocalId>>>,
+    bindings: Vec<(FxHashMap<Symbol, Vec<ItemLocalId>>, LocalDefId)>,
 }
 
 impl_lint_pass!(Shadow => [SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED]);
 
 impl<'tcx> LateLintPass<'tcx> for Shadow {
     fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
-        let (id, ident) = match pat.kind {
-            PatKind::Binding(_, hir_id, ident, _) => (hir_id, ident),
-            _ => return,
-        };
+        let PatKind::Binding(_, id, ident, _) = pat.kind else { return };
 
         if pat.span.desugaring_kind().is_some() {
             return;
@@ -116,7 +118,7 @@ fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
 
         let HirId { owner, local_id } = id;
         // get (or insert) the list of items for this owner and symbol
-        let data = self.bindings.last_mut().unwrap();
+        let (ref mut data, scope_owner) = *self.bindings.last_mut().unwrap();
         let items_with_name = data.entry(ident.name).or_default();
 
         // check other bindings with the same name, most recently seen first
@@ -126,7 +128,7 @@ fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
                 return;
             }
 
-            if is_shadow(cx, owner, prev, local_id) {
+            if is_shadow(cx, scope_owner, prev, local_id) {
                 let prev_hir_id = HirId { owner, local_id: prev };
                 lint_shadow(cx, pat, prev_hir_id, ident.span);
                 // only lint against the "nearest" shadowed binding
@@ -139,14 +141,18 @@ fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
 
     fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {
         let hir = cx.tcx.hir();
-        if !matches!(hir.body_owner_kind(hir.body_owner(body.id())), BodyOwnerKind::Closure) {
-            self.bindings.push(FxHashMap::default());
+        let owner_id = hir.body_owner_def_id(body.id());
+        if !matches!(hir.body_owner_kind(owner_id), BodyOwnerKind::Closure) {
+            self.bindings.push((FxHashMap::default(), owner_id));
         }
     }
 
     fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {
         let hir = cx.tcx.hir();
-        if !matches!(hir.body_owner_kind(hir.body_owner(body.id())), BodyOwnerKind::Closure) {
+        if !matches!(
+            hir.body_owner_kind(hir.body_owner_def_id(body.id())),
+            BodyOwnerKind::Closure
+        ) {
             self.bindings.pop();
         }
     }
@@ -154,9 +160,13 @@ fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {
 
 fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {
     let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id());
-    let first_scope = scope_tree.var_scope(first);
-    let second_scope = scope_tree.var_scope(second);
-    scope_tree.is_subscope_of(second_scope, first_scope)
+    if let Some(first_scope) = scope_tree.var_scope(first) {
+        if let Some(second_scope) = scope_tree.var_scope(second) {
+            return scope_tree.is_subscope_of(second_scope, first_scope);
+        }
+    }
+
+    false
 }
 
 fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span) {