Skip to content

Commit 1530b8b

Browse files
Fix performance regression in LintLevelsBuilder
1 parent b488f86 commit 1530b8b

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -4069,6 +4069,7 @@ dependencies = [
40694069
"rustc_target",
40704070
"rustc_trait_selection",
40714071
"rustc_type_ir",
4072+
"smallvec",
40724073
"tracing",
40734074
"unicode-security",
40744075
]

compiler/rustc_lint/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ rustc_span = { path = "../rustc_span" }
2323
rustc_target = { path = "../rustc_target" }
2424
rustc_trait_selection = { path = "../rustc_trait_selection" }
2525
rustc_type_ir = { path = "../rustc_type_ir" }
26+
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
2627
tracing = "0.1"
2728
unicode-security = "0.1.0"
2829
# tidy-alphabetical-end

compiler/rustc_lint/src/levels.rs

+21-9
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use rustc_session::parse::feature_err;
4040
use rustc_session::Session;
4141
use rustc_span::symbol::{sym, Symbol};
4242
use rustc_span::{Span, DUMMY_SP};
43+
use smallvec::SmallVec;
4344

4445
use crate::errors::{
4546
MalformedAttribute, MalformedAttributeSub, OverruledAttribute, OverruledAttributeSub,
@@ -1028,16 +1029,27 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
10281029
}
10291030

10301031
if !is_crate_node {
1031-
for (id, &(level, ref src)) in self.current_specs().to_sorted_stable_ord() {
1032-
if !id.lint.crate_level_only {
1033-
continue;
1034-
}
1035-
1036-
let LintLevelSource::Node { name: lint_attr_name, span: lint_attr_span, .. } = *src
1037-
else {
1038-
continue;
1039-
};
1032+
// Make sure we filter before collecting and sorting, so we don't
1033+
// waste time stabilizing the iteration order only to throw it away
1034+
let relevant_specs: SmallVec<[_; 8]> = self
1035+
.current_specs()
1036+
.items()
1037+
.filter(|(id, _)| id.lint.crate_level_only)
1038+
.filter_map(|(id, &(level, ref src))| {
1039+
if let LintLevelSource::Node {
1040+
name: lint_attr_name,
1041+
span: lint_attr_span,
1042+
..
1043+
} = *src
1044+
{
1045+
Some((id, level, lint_attr_name, lint_attr_span))
1046+
} else {
1047+
None
1048+
}
1049+
})
1050+
.collect_stable_ord_by_key(|&(id, ..)| id);
10401051

1052+
for (_, level, lint_attr_name, lint_attr_span) in relevant_specs {
10411053
self.emit_spanned_lint(
10421054
UNUSED_ATTRIBUTES,
10431055
lint_attr_span.into(),

0 commit comments

Comments
 (0)