about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/significant_drop_tightening.rs50
1 files changed, 18 insertions, 32 deletions
diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs
index 038eb92d652..979d6dc77ae 100644
--- a/clippy_lints/src/significant_drop_tightening.rs
+++ b/clippy_lints/src/significant_drop_tightening.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{indent_of, snippet};
 use clippy_utils::{expr_or_init, get_attr, path_to_local, peel_hir_expr_unary};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{walk_expr, Visitor};
@@ -12,6 +12,7 @@ use rustc_session::impl_lint_pass;
 use rustc_span::symbol::Ident;
 use rustc_span::{sym, Span, DUMMY_SP};
 use std::borrow::Cow;
+use std::collections::hash_map::Entry;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -57,7 +58,6 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]);
 pub struct SignificantDropTightening<'tcx> {
     apas: FxIndexMap<HirId, AuxParamsAttr>,
     /// Auxiliary structure used to avoid having to verify the same type multiple times.
-    seen_types: FxHashSet<Ty<'tcx>>,
     type_cache: FxHashMap<Ty<'tcx>, bool>,
 }
 
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
         self.apas.clear();
         let initial_dummy_stmt = dummy_stmt_expr(body.value);
         let mut ap = AuxParams::new(&mut self.apas, &initial_dummy_stmt);
-        StmtsChecker::new(&mut ap, cx, &mut self.seen_types, &mut self.type_cache).visit_body(body);
+        StmtsChecker::new(&mut ap, cx, &mut self.type_cache).visit_body(body);
         for apa in ap.apas.values() {
             if apa.counter <= 1 || !apa.has_expensive_expr_after_last_attr {
                 continue;
@@ -142,28 +142,25 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
 /// Checks the existence of the `#[has_significant_drop]` attribute.
 struct AttrChecker<'cx, 'others, 'tcx> {
     cx: &'cx LateContext<'tcx>,
-    seen_types: &'others mut FxHashSet<Ty<'tcx>>,
     type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>,
 }
 
 impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {
-    pub(crate) fn new(
-        cx: &'cx LateContext<'tcx>,
-        seen_types: &'others mut FxHashSet<Ty<'tcx>>,
-        type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>,
-    ) -> Self {
-        seen_types.clear();
-        Self {
-            cx,
-            seen_types,
-            type_cache,
-        }
+    pub(crate) fn new(cx: &'cx LateContext<'tcx>, type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>) -> Self {
+        Self { cx, type_cache }
     }
 
     fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool {
-        // The borrow checker prevents us from using something fancier like or_insert_with.
-        if let Some(ty) = self.type_cache.get(&ty) {
-            return *ty;
+        let ty = self
+            .cx
+            .tcx
+            .try_normalize_erasing_regions(self.cx.param_env, ty)
+            .unwrap_or(ty);
+        match self.type_cache.entry(ty) {
+            Entry::Occupied(e) => return *e.get(),
+            Entry::Vacant(e) => {
+                e.insert(false);
+            },
         }
         let value = self.has_sig_drop_attr_uncached(ty);
         self.type_cache.insert(ty, value);
@@ -185,7 +182,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {
             rustc_middle::ty::Adt(a, b) => {
                 for f in a.all_fields() {
                     let ty = f.ty(self.cx.tcx, b);
-                    if !self.has_seen_ty(ty) && self.has_sig_drop_attr(ty) {
+                    if self.has_sig_drop_attr(ty) {
                         return true;
                     }
                 }
@@ -205,16 +202,11 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {
             _ => false,
         }
     }
-
-    fn has_seen_ty(&mut self, ty: Ty<'tcx>) -> bool {
-        !self.seen_types.insert(ty)
-    }
 }
 
 struct StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> {
     ap: &'ap mut AuxParams<'others, 'stmt, 'tcx>,
     cx: &'lc LateContext<'tcx>,
-    seen_types: &'others mut FxHashSet<Ty<'tcx>>,
     type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>,
 }
 
@@ -222,15 +214,9 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx
     fn new(
         ap: &'ap mut AuxParams<'others, 'stmt, 'tcx>,
         cx: &'lc LateContext<'tcx>,
-        seen_types: &'others mut FxHashSet<Ty<'tcx>>,
         type_cache: &'others mut FxHashMap<Ty<'tcx>, bool>,
     ) -> Self {
-        Self {
-            ap,
-            cx,
-            seen_types,
-            type_cache,
-        }
+        Self { ap, cx, type_cache }
     }
 
     fn manage_has_expensive_expr_after_last_attr(&mut self) {
@@ -288,7 +274,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'o
             apa.counter = apa.counter.wrapping_add(1);
             apa.has_expensive_expr_after_last_attr = false;
         };
-        let mut ac = AttrChecker::new(self.cx, self.seen_types, self.type_cache);
+        let mut ac = AttrChecker::new(self.cx, self.type_cache);
         if ac.has_sig_drop_attr(self.cx.typeck_results().expr_ty(expr)) {
             if let hir::StmtKind::Let(local) = self.ap.curr_stmt.kind
                 && let hir::PatKind::Binding(_, hir_id, ident, _) = local.pat.kind