@@ -90,8 +90,8 @@ use rustc_index::{IndexSlice, IndexVec};
9090use rustc_middle:: middle:: region;
9191use rustc_middle:: mir:: * ;
9292use rustc_middle:: thir:: { Expr , LintLevel } ;
93-
9493use rustc_middle:: ty:: Ty ;
94+ use rustc_session:: lint:: Level ;
9595use rustc_span:: { Span , DUMMY_SP } ;
9696
9797#[ derive( Debug ) ]
@@ -773,8 +773,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
773773 // to avoid adding Hir dependencies on our parents.
774774 // We estimate the true lint roots here to avoid creating a lot of source scopes.
775775 (
776- self . tcx . maybe_lint_level_root_bounded ( current_id, self . hir_id ) ,
777- self . tcx . maybe_lint_level_root_bounded ( parent_id, self . hir_id ) ,
776+ self . maybe_lint_level_root_bounded ( current_id, self . hir_id ) ,
777+ self . maybe_lint_level_root_bounded ( parent_id, self . hir_id ) ,
778778 )
779779 } ;
780780
@@ -784,6 +784,27 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
784784 }
785785 }
786786
787+ /// Walks upwards from `id` to find a node which might change lint levels with attributes.
788+ /// It stops at `bound` and just returns it if reached.
789+ fn maybe_lint_level_root_bounded ( & self , mut id : HirId , bound : HirId ) -> HirId {
790+ let hir = self . tcx . hir ( ) ;
791+ loop {
792+ if id == bound {
793+ return bound;
794+ }
795+
796+ if hir. attrs ( id) . iter ( ) . any ( |attr| Level :: from_attr ( attr) . is_some ( ) ) {
797+ return id;
798+ }
799+
800+ let next = hir. parent_id ( id) ;
801+ if next == id {
802+ bug ! ( "lint traversal reached the root of the crate" ) ;
803+ }
804+ id = next;
805+ }
806+ }
807+
787808 /// Creates a new source scope, nested in the current one.
788809 pub ( crate ) fn new_source_scope (
789810 & mut self ,
0 commit comments