Skip to content

Commit d0ae7cf

Browse files
Noratriebflip1995
authored andcommitted
Cache has_sig_drop_attr for significant_drop_tightening
The lint is very slow as it doesn't cache the deeply nested check for the attribute. If we cache it, we can reduce the time spent on checking `rustc_borrowck` from 28s to 9s, which is a nice improvement. In the profile, the time inside `has_sig_drop_attr` goes from 66% to 0.2%, which is a lot more reasonable. See the PR for nice graphs.
1 parent 831d7c9 commit d0ae7cf

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs

+31-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use crate::FxHashSet;
21
use clippy_utils::{
32
diagnostics::span_lint_and_then,
43
get_attr,
54
source::{indent_of, snippet},
65
};
6+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
77
use rustc_errors::{Applicability, Diagnostic};
88
use rustc_hir::{
99
self as hir,
@@ -58,6 +58,7 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]);
5858
pub struct SignificantDropTightening<'tcx> {
5959
/// Auxiliary structure used to avoid having to verify the same type multiple times.
6060
seen_types: FxHashSet<Ty<'tcx>>,
61+
type_cache: FxHashMap<Ty<'tcx>, bool>,
6162
}
6263

6364
impl<'tcx> SignificantDropTightening<'tcx> {
@@ -118,7 +119,7 @@ impl<'tcx> SignificantDropTightening<'tcx> {
118119
stmt: &hir::Stmt<'_>,
119120
cb: impl Fn(&mut SigDropAuxParams),
120121
) {
121-
let mut sig_drop_finder = SigDropFinder::new(cx, &mut self.seen_types);
122+
let mut sig_drop_finder = SigDropFinder::new(cx, &mut self.seen_types, &mut self.type_cache);
122123
sig_drop_finder.visit_expr(expr);
123124
if sig_drop_finder.has_sig_drop {
124125
cb(sdap);
@@ -296,15 +297,24 @@ impl Default for SigDropAuxParams {
296297
struct SigDropChecker<'cx, 'sdt, 'tcx> {
297298
cx: &'cx LateContext<'tcx>,
298299
seen_types: &'sdt mut FxHashSet<Ty<'tcx>>,
300+
type_cache: &'sdt mut FxHashMap<Ty<'tcx>, bool>,
299301
}
300302

301303
impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> {
302-
pub(crate) fn new(cx: &'cx LateContext<'tcx>, seen_types: &'sdt mut FxHashSet<Ty<'tcx>>) -> Self {
304+
pub(crate) fn new(
305+
cx: &'cx LateContext<'tcx>,
306+
seen_types: &'sdt mut FxHashSet<Ty<'tcx>>,
307+
type_cache: &'sdt mut FxHashMap<Ty<'tcx>, bool>,
308+
) -> Self {
303309
seen_types.clear();
304-
Self { cx, seen_types }
310+
Self {
311+
cx,
312+
seen_types,
313+
type_cache,
314+
}
305315
}
306316

307-
pub(crate) fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool {
317+
pub(crate) fn has_sig_drop_attr_uncached(&mut self, ty: Ty<'tcx>) -> bool {
308318
if let Some(adt) = ty.ty_adt_def() {
309319
let mut iter = get_attr(
310320
self.cx.sess(),
@@ -340,6 +350,16 @@ impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> {
340350
}
341351
}
342352

353+
pub(crate) fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool {
354+
// The borrow checker prevents us from using something fancier like or_insert_with.
355+
if let Some(ty) = self.type_cache.get(&ty) {
356+
return *ty;
357+
}
358+
let value = self.has_sig_drop_attr_uncached(ty);
359+
self.type_cache.insert(ty, value);
360+
value
361+
}
362+
343363
fn has_seen_ty(&mut self, ty: Ty<'tcx>) -> bool {
344364
!self.seen_types.insert(ty)
345365
}
@@ -353,11 +373,15 @@ struct SigDropFinder<'cx, 'sdt, 'tcx> {
353373
}
354374

355375
impl<'cx, 'sdt, 'tcx> SigDropFinder<'cx, 'sdt, 'tcx> {
356-
fn new(cx: &'cx LateContext<'tcx>, seen_types: &'sdt mut FxHashSet<Ty<'tcx>>) -> Self {
376+
fn new(
377+
cx: &'cx LateContext<'tcx>,
378+
seen_types: &'sdt mut FxHashSet<Ty<'tcx>>,
379+
type_cache: &'sdt mut FxHashMap<Ty<'tcx>, bool>,
380+
) -> Self {
357381
Self {
358382
cx,
359383
has_sig_drop: false,
360-
sig_drop_checker: SigDropChecker::new(cx, seen_types),
384+
sig_drop_checker: SigDropChecker::new(cx, seen_types, type_cache),
361385
}
362386
}
363387
}

0 commit comments

Comments
 (0)