@@ -103,11 +103,12 @@ impl LintLevelSets {
103103 mut idx : LintStackIndex ,
104104 aux : Option < & FxIndexMap < LintId , LevelAndSource > > ,
105105 ) -> ( Option < Level > , LintLevelSource ) {
106- if let Some ( specs) = aux {
107- if let Some ( & ( level, src) ) = specs. get ( & id) {
108- return ( Some ( level ) , src ) ;
109- }
106+ if let Some ( specs) = aux
107+ && let Some ( & ( level, src) ) = specs. get ( & id)
108+ {
109+ return ( Some ( level ) , src ) ;
110110 }
111+
111112 loop {
112113 let LintSet { ref specs, parent } = self . list [ idx] ;
113114 if let Some ( & ( level, src) ) = specs. get ( & id) {
@@ -177,7 +178,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
177178 // There is only something to do if there are attributes at all.
178179 [ ] => { }
179180 // Most of the time, there is only one attribute. Avoid fetching HIR in that case.
180- [ ( local_id, _) ] => levels. add_id ( HirId { owner, local_id : * local_id } ) ,
181+ & [ ( local_id, _) ] => levels. add_id ( HirId { owner, local_id } ) ,
181182 // Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do
182183 // a standard visit.
183184 // FIXME(#102522) Just iterate on attrs once that iteration order matches HIR's.
@@ -643,63 +644,61 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
643644 //
644645 // This means that this only errors if we're truly lowering the lint
645646 // level from forbid.
646- if self . lint_added_lints && level != Level :: Forbid {
647- if let Level :: Forbid = old_level {
648- // Backwards compatibility check:
649- //
650- // We used to not consider `forbid(lint_group)`
651- // as preventing `allow(lint)` for some lint `lint` in
652- // `lint_group`. For now, issue a future-compatibility
653- // warning for this case.
654- let id_name = id. lint . name_lower ( ) ;
655- let fcw_warning = match old_src {
656- LintLevelSource :: Default => false ,
657- LintLevelSource :: Node { name, .. } => self . store . is_lint_group ( name) ,
658- LintLevelSource :: CommandLine ( symbol, _) => self . store . is_lint_group ( symbol) ,
659- } ;
660- debug ! (
661- "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}" ,
662- fcw_warning,
663- self . current_specs( ) ,
664- old_src,
665- id_name
666- ) ;
667- let sub = match old_src {
668- LintLevelSource :: Default => {
669- OverruledAttributeSub :: DefaultSource { id : id. to_string ( ) }
670- }
671- LintLevelSource :: Node { span, reason, .. } => {
672- OverruledAttributeSub :: NodeSource { span, reason }
673- }
674- LintLevelSource :: CommandLine ( _, _) => OverruledAttributeSub :: CommandLineSource ,
675- } ;
676- if !fcw_warning {
677- self . sess . dcx ( ) . emit_err ( OverruledAttribute {
678- span : src. span ( ) ,
647+ if self . lint_added_lints && level != Level :: Forbid && old_level == Level :: Forbid {
648+ // Backwards compatibility check:
649+ //
650+ // We used to not consider `forbid(lint_group)`
651+ // as preventing `allow(lint)` for some lint `lint` in
652+ // `lint_group`. For now, issue a future-compatibility
653+ // warning for this case.
654+ let id_name = id. lint . name_lower ( ) ;
655+ let fcw_warning = match old_src {
656+ LintLevelSource :: Default => false ,
657+ LintLevelSource :: Node { name, .. } => self . store . is_lint_group ( name) ,
658+ LintLevelSource :: CommandLine ( symbol, _) => self . store . is_lint_group ( symbol) ,
659+ } ;
660+ debug ! (
661+ "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}" ,
662+ fcw_warning,
663+ self . current_specs( ) ,
664+ old_src,
665+ id_name
666+ ) ;
667+ let sub = match old_src {
668+ LintLevelSource :: Default => {
669+ OverruledAttributeSub :: DefaultSource { id : id. to_string ( ) }
670+ }
671+ LintLevelSource :: Node { span, reason, .. } => {
672+ OverruledAttributeSub :: NodeSource { span, reason }
673+ }
674+ LintLevelSource :: CommandLine ( _, _) => OverruledAttributeSub :: CommandLineSource ,
675+ } ;
676+ if !fcw_warning {
677+ self . sess . dcx ( ) . emit_err ( OverruledAttribute {
678+ span : src. span ( ) ,
679+ overruled : src. span ( ) ,
680+ lint_level : level. as_str ( ) ,
681+ lint_source : src. name ( ) ,
682+ sub,
683+ } ) ;
684+ } else {
685+ self . emit_span_lint (
686+ FORBIDDEN_LINT_GROUPS ,
687+ src. span ( ) . into ( ) ,
688+ OverruledAttributeLint {
679689 overruled : src. span ( ) ,
680690 lint_level : level. as_str ( ) ,
681691 lint_source : src. name ( ) ,
682692 sub,
683- } ) ;
684- } else {
685- self . emit_span_lint (
686- FORBIDDEN_LINT_GROUPS ,
687- src. span ( ) . into ( ) ,
688- OverruledAttributeLint {
689- overruled : src. span ( ) ,
690- lint_level : level. as_str ( ) ,
691- lint_source : src. name ( ) ,
692- sub,
693- } ,
694- ) ;
695- }
693+ } ,
694+ ) ;
695+ }
696696
697- // Retain the forbid lint level, unless we are
698- // issuing a FCW. In the FCW case, we want to
699- // respect the new setting.
700- if !fcw_warning {
701- return ;
702- }
697+ // Retain the forbid lint level, unless we are
698+ // issuing a FCW. In the FCW case, we want to
699+ // respect the new setting.
700+ if !fcw_warning {
701+ return ;
703702 }
704703 }
705704
@@ -770,15 +769,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
770769
771770 let Some ( mut metas) = attr. meta_item_list ( ) else { continue } ;
772771
773- if metas. is_empty ( ) {
772+ // Check whether `metas` is empty, and get its last element.
773+ let Some ( tail_li) = metas. last ( ) else {
774774 // This emits the unused_attributes lint for `#[level()]`
775775 continue ;
776- }
776+ } ;
777777
778778 // Before processing the lint names, look for a reason (RFC 2383)
779779 // at the end.
780780 let mut reason = None ;
781- let tail_li = & metas[ metas. len ( ) - 1 ] ;
782781 if let Some ( item) = tail_li. meta_item ( ) {
783782 match item. kind {
784783 ast:: MetaItemKind :: Word => { } // actual lint names handled later
@@ -834,21 +833,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
834833 let meta_item = match li {
835834 ast:: NestedMetaItem :: MetaItem ( meta_item) if meta_item. is_word ( ) => meta_item,
836835 _ => {
837- if let Some ( item) = li. meta_item ( ) {
838- if let ast:: MetaItemKind :: NameValue ( _) = item. kind {
839- if item. path == sym:: reason {
840- sess. dcx ( ) . emit_err ( MalformedAttribute {
841- span : sp,
842- sub : MalformedAttributeSub :: ReasonMustComeLast ( sp) ,
843- } ) ;
844- continue ;
845- }
846- }
847- }
848- sess. dcx ( ) . emit_err ( MalformedAttribute {
849- span : sp,
850- sub : MalformedAttributeSub :: BadAttributeArgument ( sp) ,
851- } ) ;
836+ let sub = if let Some ( item) = li. meta_item ( )
837+ && let ast:: MetaItemKind :: NameValue ( _) = item. kind
838+ && item. path == sym:: reason
839+ {
840+ MalformedAttributeSub :: ReasonMustComeLast ( sp)
841+ } else {
842+ MalformedAttributeSub :: BadAttributeArgument ( sp)
843+ } ;
844+
845+ sess. dcx ( ) . emit_err ( MalformedAttribute { span : sp, sub } ) ;
852846 continue ;
853847 }
854848 } ;
@@ -987,11 +981,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
987981 }
988982
989983 CheckLintNameResult :: NoLint ( suggestion) => {
990- let name = if let Some ( tool_ident) = tool_ident {
991- format ! ( "{}::{}" , tool_ident. name, name)
992- } else {
993- name. to_string ( )
994- } ;
984+ let name = tool_ident. map ( |tool| format ! ( "{tool}::{name}" ) ) . unwrap_or ( name) ;
995985 let suggestion = suggestion. map ( |( replace, from_rustc) | {
996986 UnknownLintSuggestion :: WithSpan { suggestion : sp, replace, from_rustc }
997987 } ) ;
@@ -1005,27 +995,24 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
1005995 if let CheckLintNameResult :: Renamed ( new_name) = lint_result {
1006996 // Ignore any errors or warnings that happen because the new name is inaccurate
1007997 // NOTE: `new_name` already includes the tool name, so we don't have to add it again.
1008- if let CheckLintNameResult :: Ok ( ids) =
998+ let CheckLintNameResult :: Ok ( ids) =
1009999 self . store . check_lint_name ( & new_name, None , self . registered_tools )
1010- {
1011- let src = LintLevelSource :: Node {
1012- name : Symbol :: intern ( & new_name) ,
1013- span : sp,
1014- reason,
1015- } ;
1016- for & id in ids {
1017- if self . check_gated_lint ( id, attr. span , false ) {
1018- self . insert_spec ( id, ( level, src) ) ;
1019- }
1020- }
1021- if let Level :: Expect ( expect_id) = level {
1022- self . provider . push_expectation (
1023- expect_id,
1024- LintExpectation :: new ( reason, sp, false , tool_name) ,
1025- ) ;
1026- }
1027- } else {
1000+ else {
10281001 panic ! ( "renamed lint does not exist: {new_name}" ) ;
1002+ } ;
1003+
1004+ let src =
1005+ LintLevelSource :: Node { name : Symbol :: intern ( & new_name) , span : sp, reason } ;
1006+ for & id in ids {
1007+ if self . check_gated_lint ( id, attr. span , false ) {
1008+ self . insert_spec ( id, ( level, src) ) ;
1009+ }
1010+ }
1011+ if let Level :: Expect ( expect_id) = level {
1012+ self . provider . push_expectation (
1013+ expect_id,
1014+ LintExpectation :: new ( reason, sp, false , tool_name) ,
1015+ ) ;
10291016 }
10301017 }
10311018 }
@@ -1058,38 +1045,44 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
10581045 /// Returns `true` if the lint's feature is enabled.
10591046 #[ track_caller]
10601047 fn check_gated_lint ( & self , lint_id : LintId , span : Span , lint_from_cli : bool ) -> bool {
1061- if let Some ( feature) = lint_id. lint . feature_gate {
1062- if !self . features . active ( feature) {
1063- if self . lint_added_lints {
1064- let lint = builtin:: UNKNOWN_LINTS ;
1065- let ( level, src) = self . lint_level ( builtin:: UNKNOWN_LINTS ) ;
1066- // FIXME: make this translatable
1067- #[ allow( rustc:: diagnostic_outside_of_impl) ]
1068- #[ allow( rustc:: untranslatable_diagnostic) ]
1069- lint_level (
1070- self . sess ,
1048+ let feature = if let Some ( feature) = lint_id. lint . feature_gate
1049+ && !self . features . active ( feature)
1050+ {
1051+ // Lint is behind a feature that is not enabled; eventually return false.
1052+ feature
1053+ } else {
1054+ // Lint is ungated or its feature is enabled; exit early.
1055+ return true ;
1056+ } ;
1057+
1058+ if self . lint_added_lints {
1059+ let lint = builtin:: UNKNOWN_LINTS ;
1060+ let ( level, src) = self . lint_level ( builtin:: UNKNOWN_LINTS ) ;
1061+ // FIXME: make this translatable
1062+ #[ allow( rustc:: diagnostic_outside_of_impl) ]
1063+ #[ allow( rustc:: untranslatable_diagnostic) ]
1064+ lint_level (
1065+ self . sess ,
1066+ lint,
1067+ level,
1068+ src,
1069+ Some ( span. into ( ) ) ,
1070+ fluent:: lint_unknown_gated_lint,
1071+ |lint| {
1072+ lint. arg ( "name" , lint_id. lint . name_lower ( ) ) ;
1073+ lint. note ( fluent:: lint_note) ;
1074+ rustc_session:: parse:: add_feature_diagnostics_for_issue (
10711075 lint,
1072- level,
1073- src,
1074- Some ( span. into ( ) ) ,
1075- fluent:: lint_unknown_gated_lint,
1076- |lint| {
1077- lint. arg ( "name" , lint_id. lint . name_lower ( ) ) ;
1078- lint. note ( fluent:: lint_note) ;
1079- rustc_session:: parse:: add_feature_diagnostics_for_issue (
1080- lint,
1081- & self . sess ,
1082- feature,
1083- GateIssue :: Language ,
1084- lint_from_cli,
1085- ) ;
1086- } ,
1076+ & self . sess ,
1077+ feature,
1078+ GateIssue :: Language ,
1079+ lint_from_cli,
10871080 ) ;
1088- }
1089- return false ;
1090- }
1081+ } ,
1082+ ) ;
10911083 }
1092- true
1084+
1085+ false
10931086 }
10941087
10951088 /// Find the lint level for a lint.
0 commit comments