@@ -135,6 +135,7 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
135135#[ instrument( level = "trace" , skip( tcx) , ret) ]
136136fn shallow_lint_levels_on ( tcx : TyCtxt < ' _ > , owner : hir:: OwnerId ) -> ShallowLintLevelMap {
137137 let store = unerased_lint_store ( tcx) ;
138+ let attrs = tcx. hir_attrs ( owner) ;
138139
139140 let mut levels = LintLevelsBuilder {
140141 sess : tcx. sess ,
@@ -143,23 +144,35 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
143144 cur : owner. into ( ) ,
144145 specs : ShallowLintLevelMap :: default ( ) ,
145146 empty : FxHashMap :: default ( ) ,
147+ attrs,
146148 } ,
147149 warn_about_weird_lints : false ,
148150 store,
149151 registered_tools : & tcx. resolutions ( ( ) ) . registered_tools ,
150152 } ;
151153
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+ }
163176
164177 let mut specs = levels. provider . specs ;
165178 specs. specs . retain ( |( _, v) | !v. is_empty ( ) ) ;
@@ -199,6 +212,7 @@ struct LintLevelQueryMap<'tcx> {
199212 specs : ShallowLintLevelMap ,
200213 /// Empty hash map to simplify code.
201214 empty : FxHashMap < LintId , LevelAndSource > ,
215+ attrs : & ' tcx hir:: AttributeMap < ' tcx > ,
202216}
203217
204218impl LintLevelsProvider for LintLevelQueryMap < ' _ > {
@@ -253,7 +267,11 @@ impl LintLevelsProvider for QueryMapExpectationsWrapper<'_> {
253267impl < ' tcx > LintLevelsBuilder < ' _ , LintLevelQueryMap < ' tcx > > {
254268 fn add_id ( & mut self , hir_id : HirId ) {
255269 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+ ) ;
257275 }
258276}
259277
0 commit comments