@@ -135,6 +135,7 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
135
135
#[ instrument( level = "trace" , skip( tcx) , ret) ]
136
136
fn shallow_lint_levels_on ( tcx : TyCtxt < ' _ > , owner : hir:: OwnerId ) -> ShallowLintLevelMap {
137
137
let store = unerased_lint_store ( tcx) ;
138
+ let attrs = tcx. hir_attrs ( owner) ;
138
139
139
140
let mut levels = LintLevelsBuilder {
140
141
sess : tcx. sess ,
@@ -143,23 +144,35 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
143
144
cur : owner. into ( ) ,
144
145
specs : ShallowLintLevelMap :: default ( ) ,
145
146
empty : FxHashMap :: default ( ) ,
147
+ attrs,
146
148
} ,
147
149
warn_about_weird_lints : false ,
148
150
store,
149
151
registered_tools : & tcx. resolutions ( ( ) ) . registered_tools ,
150
152
} ;
151
153
152
- match tcx. hir ( ) . expect_owner ( owner) {
153
- hir:: OwnerNode :: Item ( item) => levels. visit_item ( item) ,
154
- hir:: OwnerNode :: ForeignItem ( item) => levels. visit_foreign_item ( item) ,
155
- hir:: OwnerNode :: TraitItem ( item) => levels. visit_trait_item ( item) ,
156
- hir:: OwnerNode :: ImplItem ( item) => levels. visit_impl_item ( item) ,
157
- hir:: OwnerNode :: Crate ( mod_) => {
158
- levels. add_command_line ( ) ;
159
- levels. add_id ( hir:: CRATE_HIR_ID ) ;
160
- levels. visit_mod ( mod_, mod_. spans . inner_span , hir:: CRATE_HIR_ID )
161
- }
162
- } ;
154
+ if owner == hir:: CRATE_OWNER_ID {
155
+ levels. add_command_line ( ) ;
156
+ }
157
+
158
+ match attrs. map . range ( ..) {
159
+ // There is only something to do if there are attributes at all.
160
+ [ ] => { }
161
+ // Most of the time, there is only one attribute. Avoid fetching HIR in that case.
162
+ [ ( local_id, _) ] => levels. add_id ( HirId { owner, local_id : * local_id } ) ,
163
+ // Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do
164
+ // a standard visit.
165
+ _ => match tcx. hir ( ) . expect_owner ( owner) {
166
+ hir:: OwnerNode :: Item ( item) => levels. visit_item ( item) ,
167
+ hir:: OwnerNode :: ForeignItem ( item) => levels. visit_foreign_item ( item) ,
168
+ hir:: OwnerNode :: TraitItem ( item) => levels. visit_trait_item ( item) ,
169
+ hir:: OwnerNode :: ImplItem ( item) => levels. visit_impl_item ( item) ,
170
+ hir:: OwnerNode :: Crate ( mod_) => {
171
+ levels. add_id ( hir:: CRATE_HIR_ID ) ;
172
+ levels. visit_mod ( mod_, mod_. spans . inner_span , hir:: CRATE_HIR_ID )
173
+ }
174
+ } ,
175
+ }
163
176
164
177
let mut specs = levels. provider . specs ;
165
178
specs. specs . retain ( |( _, v) | !v. is_empty ( ) ) ;
@@ -199,6 +212,7 @@ struct LintLevelQueryMap<'tcx> {
199
212
specs : ShallowLintLevelMap ,
200
213
/// Empty hash map to simplify code.
201
214
empty : FxHashMap < LintId , LevelAndSource > ,
215
+ attrs : & ' tcx hir:: AttributeMap < ' tcx > ,
202
216
}
203
217
204
218
impl LintLevelsProvider for LintLevelQueryMap < ' _ > {
@@ -253,7 +267,11 @@ impl LintLevelsProvider for QueryMapExpectationsWrapper<'_> {
253
267
impl < ' tcx > LintLevelsBuilder < ' _ , LintLevelQueryMap < ' tcx > > {
254
268
fn add_id ( & mut self , hir_id : HirId ) {
255
269
self . provider . cur = hir_id;
256
- self . add ( self . provider . tcx . hir ( ) . attrs ( hir_id) , hir_id == hir:: CRATE_HIR_ID , Some ( hir_id) ) ;
270
+ self . add (
271
+ self . provider . attrs . get ( hir_id. local_id ) ,
272
+ hir_id == hir:: CRATE_HIR_ID ,
273
+ Some ( hir_id) ,
274
+ ) ;
257
275
}
258
276
}
259
277
0 commit comments