@@ -40,6 +40,7 @@ use rustc_session::parse::feature_err;
40
40
use rustc_session:: Session ;
41
41
use rustc_span:: symbol:: { sym, Symbol } ;
42
42
use rustc_span:: { Span , DUMMY_SP } ;
43
+ use smallvec:: SmallVec ;
43
44
44
45
use crate :: errors:: {
45
46
MalformedAttribute , MalformedAttributeSub , OverruledAttribute , OverruledAttributeSub ,
@@ -1028,16 +1029,27 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
1028
1029
}
1029
1030
1030
1031
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) ;
1040
1051
1052
+ for ( _, level, lint_attr_name, lint_attr_span) in relevant_specs {
1041
1053
self . emit_spanned_lint (
1042
1054
UNUSED_ATTRIBUTES ,
1043
1055
lint_attr_span. into ( ) ,
0 commit comments