@@ -84,28 +84,28 @@ impl LintLevelSets {
8484 ) -> LevelAndSource {
8585 let lint = LintId :: of ( lint) ;
8686 let ( level, mut src) = self . raw_lint_id_level ( lint, idx, aux) ;
87- let level = reveal_actual_level ( level, & mut src, sess, lint, |id| {
87+ let ( level, lint_id ) = reveal_actual_level ( level, & mut src, sess, lint, |id| {
8888 self . raw_lint_id_level ( id, idx, aux)
8989 } ) ;
90- LevelAndSource { level, src }
90+ LevelAndSource { level, lint_id , src }
9191 }
9292
9393 fn raw_lint_id_level (
9494 & self ,
9595 id : LintId ,
9696 mut idx : LintStackIndex ,
9797 aux : Option < & FxIndexMap < LintId , LevelAndSource > > ,
98- ) -> ( Option < Level > , LintLevelSource ) {
98+ ) -> ( Option < ( Level , Option < LintExpectationId > ) > , LintLevelSource ) {
9999 if let Some ( specs) = aux
100- && let Some ( & LevelAndSource { level, src } ) = specs. get ( & id)
100+ && let Some ( & LevelAndSource { level, lint_id , src } ) = specs. get ( & id)
101101 {
102- return ( Some ( level) , src) ;
102+ return ( Some ( ( level, lint_id ) ) , src) ;
103103 }
104104
105105 loop {
106106 let LintSet { ref specs, parent } = self . list [ idx] ;
107- if let Some ( & LevelAndSource { level, src } ) = specs. get ( & id) {
108- return ( Some ( level) , src) ;
107+ if let Some ( & LevelAndSource { level, lint_id , src } ) = specs. get ( & id) {
108+ return ( Some ( ( level, lint_id ) ) , src) ;
109109 }
110110 if idx == COMMAND_LINE {
111111 return ( None , LintLevelSource :: Default ) ;
@@ -379,13 +379,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelMaximum<'tcx> {
379379 fn visit_attribute ( & mut self , attribute : & ' tcx hir:: Attribute ) {
380380 if matches ! (
381381 Level :: from_attr( attribute) ,
382- Some (
383- Level :: Warn
384- | Level :: Deny
385- | Level :: Forbid
386- | Level :: Expect ( ..)
387- | Level :: ForceWarn ( ..) ,
388- )
382+ Some ( ( Level :: Warn | Level :: Deny | Level :: Forbid | Level :: Expect | Level :: ForceWarn , _) )
389383 ) {
390384 let store = unerased_lint_store ( self . tcx . sess ) ;
391385 // Lint attributes are always a metalist inside a
@@ -541,9 +535,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
541535 for & ( ref lint_name, level) in & self . sess . opts . lint_opts {
542536 // Checks the validity of lint names derived from the command line.
543537 let ( tool_name, lint_name_only) = parse_lint_and_tool_name ( lint_name) ;
544- if lint_name_only == crate :: WARNINGS . name_lower ( )
545- && matches ! ( level, Level :: ForceWarn ( _) )
546- {
538+ if lint_name_only == crate :: WARNINGS . name_lower ( ) && matches ! ( level, Level :: ForceWarn ) {
547539 self . sess
548540 . dcx ( )
549541 . emit_err ( UnsupportedGroup { lint_group : crate :: WARNINGS . name_lower ( ) } ) ;
@@ -586,7 +578,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
586578 _ => { }
587579 } ;
588580
589- let orig_level = level;
590581 let lint_flag_val = Symbol :: intern ( lint_name) ;
591582
592583 let Ok ( ids) = self . store . find_lints ( lint_name) else {
@@ -595,15 +586,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
595586 } ;
596587 for id in ids {
597588 // ForceWarn and Forbid cannot be overridden
598- if let Some ( LevelAndSource { level : Level :: ForceWarn ( _ ) | Level :: Forbid , .. } ) =
589+ if let Some ( LevelAndSource { level : Level :: ForceWarn | Level :: Forbid , .. } ) =
599590 self . current_specs ( ) . get ( & id)
600591 {
601592 continue ;
602593 }
603594
604595 if self . check_gated_lint ( id, DUMMY_SP , true ) {
605- let src = LintLevelSource :: CommandLine ( lint_flag_val, orig_level ) ;
606- self . insert ( id, LevelAndSource { level, src } ) ;
596+ let src = LintLevelSource :: CommandLine ( lint_flag_val, level ) ;
597+ self . insert ( id, LevelAndSource { level, lint_id : None , src } ) ;
607598 }
608599 }
609600 }
@@ -612,8 +603,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
612603 /// Attempts to insert the `id` to `level_src` map entry. If unsuccessful
613604 /// (e.g. if a forbid was already inserted on the same scope), then emits a
614605 /// diagnostic with no change to `specs`.
615- fn insert_spec ( & mut self , id : LintId , LevelAndSource { level, src } : LevelAndSource ) {
616- let LevelAndSource { level : old_level, src : old_src } =
606+ fn insert_spec ( & mut self , id : LintId , LevelAndSource { level, lint_id , src } : LevelAndSource ) {
607+ let LevelAndSource { level : old_level, src : old_src, .. } =
617608 self . provider . get_lint_level ( id. lint , self . sess ) ;
618609
619610 // Setting to a non-forbid level is an error if the lint previously had
@@ -686,24 +677,24 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
686677 // The lint `unfulfilled_lint_expectations` can't be expected, as it would suppress itself.
687678 // Handling expectations of this lint would add additional complexity with little to no
688679 // benefit. The expect level for this lint will therefore be ignored.
689- if let Level :: Expect ( _ ) = level
680+ if let Level :: Expect = level
690681 && id == LintId :: of ( UNFULFILLED_LINT_EXPECTATIONS )
691682 {
692683 return ;
693684 }
694685
695686 match ( old_level, level) {
696687 // If the new level is an expectation store it in `ForceWarn`
697- ( Level :: ForceWarn ( _) , Level :: Expect ( expectation_id) ) => self . insert (
688+ ( Level :: ForceWarn , Level :: Expect ) => {
689+ self . insert ( id, LevelAndSource { level : Level :: ForceWarn , lint_id, src : old_src } )
690+ }
691+ // Keep `ForceWarn` level but drop the expectation
692+ ( Level :: ForceWarn , _) => self . insert (
698693 id,
699- LevelAndSource { level : Level :: ForceWarn ( Some ( expectation_id ) ) , src : old_src } ,
694+ LevelAndSource { level : Level :: ForceWarn , lint_id : None , src : old_src } ,
700695 ) ,
701- // Keep `ForceWarn` level but drop the expectation
702- ( Level :: ForceWarn ( _) , _) => {
703- self . insert ( id, LevelAndSource { level : Level :: ForceWarn ( None ) , src : old_src } )
704- }
705696 // Set the lint level as normal
706- _ => self . insert ( id, LevelAndSource { level, src } ) ,
697+ _ => self . insert ( id, LevelAndSource { level, lint_id , src } ) ,
707698 } ;
708699 }
709700
@@ -718,7 +709,11 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
718709 if attr. has_name ( sym:: automatically_derived) {
719710 self . insert (
720711 LintId :: of ( SINGLE_USE_LIFETIMES ) ,
721- LevelAndSource { level : Level :: Allow , src : LintLevelSource :: Default } ,
712+ LevelAndSource {
713+ level : Level :: Allow ,
714+ lint_id : None ,
715+ src : LintLevelSource :: Default ,
716+ } ,
722717 ) ;
723718 continue ;
724719 }
@@ -731,16 +726,20 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
731726 {
732727 self . insert (
733728 LintId :: of ( MISSING_DOCS ) ,
734- LevelAndSource { level : Level :: Allow , src : LintLevelSource :: Default } ,
729+ LevelAndSource {
730+ level : Level :: Allow ,
731+ lint_id : None ,
732+ src : LintLevelSource :: Default ,
733+ } ,
735734 ) ;
736735 continue ;
737736 }
738737
739- let level = match Level :: from_attr ( attr) {
738+ let ( level, lint_id ) = match Level :: from_attr ( attr) {
740739 None => continue ,
741740 // This is the only lint level with a `LintExpectationId` that can be created from
742741 // an attribute.
743- Some ( Level :: Expect ( unstable_id) ) if let Some ( hir_id) = source_hir_id => {
742+ Some ( ( Level :: Expect , Some ( unstable_id) ) ) if let Some ( hir_id) = source_hir_id => {
744743 let LintExpectationId :: Unstable { lint_index : None , attr_id : _ } = unstable_id
745744 else {
746745 bug ! ( "stable id Level::from_attr" )
@@ -752,9 +751,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
752751 lint_index : None ,
753752 } ;
754753
755- Level :: Expect ( stable_id)
754+ ( Level :: Expect , Some ( stable_id) )
756755 }
757- Some ( lvl) => lvl,
756+ Some ( ( lvl, id ) ) => ( lvl, id ) ,
758757 } ;
759758
760759 let Some ( mut metas) = attr. meta_item_list ( ) else { continue } ;
@@ -802,13 +801,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
802801 }
803802
804803 for ( lint_index, li) in metas. iter_mut ( ) . enumerate ( ) {
805- let level = match level {
806- Level :: Expect ( mut id) => {
807- id. set_lint_index ( Some ( lint_index as u16 ) ) ;
808- Level :: Expect ( id)
809- }
810- level => level,
811- } ;
804+ let mut lint_id = lint_id;
805+ if let Some ( id) = & mut lint_id {
806+ id. set_lint_index ( Some ( lint_index as u16 ) ) ;
807+ }
812808
813809 let sp = li. span ( ) ;
814810 let meta_item = match li {
@@ -940,7 +936,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
940936 let src = LintLevelSource :: Node { name, span : sp, reason } ;
941937 for & id in ids {
942938 if self . check_gated_lint ( id, sp, false ) {
943- self . insert_spec ( id, LevelAndSource { level, src } ) ;
939+ self . insert_spec ( id, LevelAndSource { level, lint_id , src } ) ;
944940 }
945941 }
946942
@@ -949,7 +945,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
949945 // overriding the lint level but instead add an expectation that can't be
950946 // fulfilled. The lint message will include an explanation, that the
951947 // `unfulfilled_lint_expectations` lint can't be expected.
952- if let Level :: Expect ( expect_id) = level {
948+ if let ( Level :: Expect , Some ( expect_id) ) = ( level, lint_id ) {
953949 // The `unfulfilled_lint_expectations` lint is not part of any lint
954950 // groups. Therefore. we only need to check the slice if it contains a
955951 // single lint.
@@ -971,7 +967,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
971967 }
972968
973969 if self . lint_added_lints && !is_crate_node {
974- for ( id, & LevelAndSource { level, ref src } ) in self . current_specs ( ) . iter ( ) {
970+ for ( id, & LevelAndSource { level, ref src, .. } ) in self . current_specs ( ) . iter ( ) {
975971 if !id. lint . crate_level_only {
976972 continue ;
977973 }
0 commit comments