@@ -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.
@@ -644,63 +645,61 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
644645 //
645646 // This means that this only errors if we're truly lowering the lint
646647 // level from forbid.
647- if self . lint_added_lints && level != Level :: Forbid {
648- if let Level :: Forbid = old_level {
649- // Backwards compatibility check:
650- //
651- // We used to not consider `forbid(lint_group)`
652- // as preventing `allow(lint)` for some lint `lint` in
653- // `lint_group`. For now, issue a future-compatibility
654- // warning for this case.
655- let id_name = id. lint . name_lower ( ) ;
656- let fcw_warning = match old_src {
657- LintLevelSource :: Default => false ,
658- LintLevelSource :: Node { name, .. } => self . store . is_lint_group ( name) ,
659- LintLevelSource :: CommandLine ( symbol, _) => self . store . is_lint_group ( symbol) ,
660- } ;
661- debug ! (
662- "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}" ,
663- fcw_warning,
664- self . current_specs( ) ,
665- old_src,
666- id_name
667- ) ;
668- let sub = match old_src {
669- LintLevelSource :: Default => {
670- OverruledAttributeSub :: DefaultSource { id : id. to_string ( ) }
671- }
672- LintLevelSource :: Node { span, reason, .. } => {
673- OverruledAttributeSub :: NodeSource { span, reason }
674- }
675- LintLevelSource :: CommandLine ( _, _) => OverruledAttributeSub :: CommandLineSource ,
676- } ;
677- if !fcw_warning {
678- self . sess . dcx ( ) . emit_err ( OverruledAttribute {
679- span : src. span ( ) ,
648+ if self . lint_added_lints && level != Level :: Forbid && old_level == Level :: Forbid {
649+ // Backwards compatibility check:
650+ //
651+ // We used to not consider `forbid(lint_group)`
652+ // as preventing `allow(lint)` for some lint `lint` in
653+ // `lint_group`. For now, issue a future-compatibility
654+ // warning for this case.
655+ let id_name = id. lint . name_lower ( ) ;
656+ let fcw_warning = match old_src {
657+ LintLevelSource :: Default => false ,
658+ LintLevelSource :: Node { name, .. } => self . store . is_lint_group ( name) ,
659+ LintLevelSource :: CommandLine ( symbol, _) => self . store . is_lint_group ( symbol) ,
660+ } ;
661+ debug ! (
662+ "fcw_warning={:?}, specs.get(&id) = {:?}, old_src={:?}, id_name={:?}" ,
663+ fcw_warning,
664+ self . current_specs( ) ,
665+ old_src,
666+ id_name
667+ ) ;
668+ let sub = match old_src {
669+ LintLevelSource :: Default => {
670+ OverruledAttributeSub :: DefaultSource { id : id. to_string ( ) }
671+ }
672+ LintLevelSource :: Node { span, reason, .. } => {
673+ OverruledAttributeSub :: NodeSource { span, reason }
674+ }
675+ LintLevelSource :: CommandLine ( _, _) => OverruledAttributeSub :: CommandLineSource ,
676+ } ;
677+ if !fcw_warning {
678+ self . sess . dcx ( ) . emit_err ( OverruledAttribute {
679+ span : src. span ( ) ,
680+ overruled : src. span ( ) ,
681+ lint_level : level. as_str ( ) ,
682+ lint_source : src. name ( ) ,
683+ sub,
684+ } ) ;
685+ } else {
686+ self . emit_span_lint (
687+ FORBIDDEN_LINT_GROUPS ,
688+ src. span ( ) . into ( ) ,
689+ OverruledAttributeLint {
680690 overruled : src. span ( ) ,
681691 lint_level : level. as_str ( ) ,
682692 lint_source : src. name ( ) ,
683693 sub,
684- } ) ;
685- } else {
686- self . emit_span_lint (
687- FORBIDDEN_LINT_GROUPS ,
688- src. span ( ) . into ( ) ,
689- OverruledAttributeLint {
690- overruled : src. span ( ) ,
691- lint_level : level. as_str ( ) ,
692- lint_source : src. name ( ) ,
693- sub,
694- } ,
695- ) ;
696- }
694+ } ,
695+ ) ;
696+ }
697697
698- // Retain the forbid lint level, unless we are
699- // issuing a FCW. In the FCW case, we want to
700- // respect the new setting.
701- if !fcw_warning {
702- return ;
703- }
698+ // Retain the forbid lint level, unless we are
699+ // issuing a FCW. In the FCW case, we want to
700+ // respect the new setting.
701+ if !fcw_warning {
702+ return ;
704703 }
705704 }
706705
@@ -771,15 +770,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
771770
772771 let Some ( mut metas) = attr. meta_item_list ( ) else { continue } ;
773772
774- if metas. is_empty ( ) {
773+ // Check whether `metas` is empty, and get its last element.
774+ let Some ( tail_li) = metas. last ( ) else {
775775 // This emits the unused_attributes lint for `#[level()]`
776776 continue ;
777- }
777+ } ;
778778
779779 // Before processing the lint names, look for a reason (RFC 2383)
780780 // at the end.
781781 let mut reason = None ;
782- let tail_li = & metas[ metas. len ( ) - 1 ] ;
783782 if let Some ( item) = tail_li. meta_item ( ) {
784783 match item. kind {
785784 ast:: MetaItemKind :: Word => { } // actual lint names handled later
@@ -835,21 +834,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
835834 let meta_item = match li {
836835 ast:: NestedMetaItem :: MetaItem ( meta_item) if meta_item. is_word ( ) => meta_item,
837836 _ => {
838- if let Some ( item) = li. meta_item ( ) {
839- if let ast:: MetaItemKind :: NameValue ( _) = item. kind {
840- if item. path == sym:: reason {
841- sess. dcx ( ) . emit_err ( MalformedAttribute {
842- span : sp,
843- sub : MalformedAttributeSub :: ReasonMustComeLast ( sp) ,
844- } ) ;
845- continue ;
846- }
847- }
848- }
849- sess. dcx ( ) . emit_err ( MalformedAttribute {
850- span : sp,
851- sub : MalformedAttributeSub :: BadAttributeArgument ( sp) ,
852- } ) ;
837+ let sub = if let Some ( item) = li. meta_item ( )
838+ && let ast:: MetaItemKind :: NameValue ( _) = item. kind
839+ && item. path == sym:: reason
840+ {
841+ MalformedAttributeSub :: ReasonMustComeLast ( sp)
842+ } else {
843+ MalformedAttributeSub :: BadAttributeArgument ( sp)
844+ } ;
845+
846+ sess. dcx ( ) . emit_err ( MalformedAttribute { span : sp, sub } ) ;
853847 continue ;
854848 }
855849 } ;
@@ -988,11 +982,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
988982 }
989983
990984 CheckLintNameResult :: NoLint ( suggestion) => {
991- let name = if let Some ( tool_ident) = tool_ident {
992- format ! ( "{}::{}" , tool_ident. name, name)
993- } else {
994- name. to_string ( )
995- } ;
985+ let name = tool_ident. map ( |tool| format ! ( "{tool}::{name}" ) ) . unwrap_or ( name) ;
996986 let suggestion = suggestion. map ( |( replace, from_rustc) | {
997987 UnknownLintSuggestion :: WithSpan { suggestion : sp, replace, from_rustc }
998988 } ) ;
@@ -1006,27 +996,24 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
1006996 if let CheckLintNameResult :: Renamed ( new_name) = lint_result {
1007997 // Ignore any errors or warnings that happen because the new name is inaccurate
1008998 // NOTE: `new_name` already includes the tool name, so we don't have to add it again.
1009- if let CheckLintNameResult :: Ok ( ids) =
999+ let CheckLintNameResult :: Ok ( ids) =
10101000 self . store . check_lint_name ( & new_name, None , self . registered_tools )
1011- {
1012- let src = LintLevelSource :: Node {
1013- name : Symbol :: intern ( & new_name) ,
1014- span : sp,
1015- reason,
1016- } ;
1017- for & id in ids {
1018- if self . check_gated_lint ( id, attr. span , false ) {
1019- self . insert_spec ( id, ( level, src) ) ;
1020- }
1021- }
1022- if let Level :: Expect ( expect_id) = level {
1023- self . provider . push_expectation (
1024- expect_id,
1025- LintExpectation :: new ( reason, sp, false , tool_name) ,
1026- ) ;
1027- }
1028- } else {
1001+ else {
10291002 panic ! ( "renamed lint does not exist: {new_name}" ) ;
1003+ } ;
1004+
1005+ let src =
1006+ LintLevelSource :: Node { name : Symbol :: intern ( & new_name) , span : sp, reason } ;
1007+ for & id in ids {
1008+ if self . check_gated_lint ( id, attr. span , false ) {
1009+ self . insert_spec ( id, ( level, src) ) ;
1010+ }
1011+ }
1012+ if let Level :: Expect ( expect_id) = level {
1013+ self . provider . push_expectation (
1014+ expect_id,
1015+ LintExpectation :: new ( reason, sp, false , tool_name) ,
1016+ ) ;
10301017 }
10311018 }
10321019 }
@@ -1059,38 +1046,44 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
10591046 /// Returns `true` if the lint's feature is enabled.
10601047 #[ track_caller]
10611048 fn check_gated_lint ( & self , lint_id : LintId , span : Span , lint_from_cli : bool ) -> bool {
1062- if let Some ( feature) = lint_id. lint . feature_gate {
1063- if !self . features . active ( feature) {
1064- if self . lint_added_lints {
1065- let lint = builtin:: UNKNOWN_LINTS ;
1066- let ( level, src) = self . lint_level ( builtin:: UNKNOWN_LINTS ) ;
1067- // FIXME: make this translatable
1068- #[ allow( rustc:: diagnostic_outside_of_impl) ]
1069- #[ allow( rustc:: untranslatable_diagnostic) ]
1070- lint_level (
1071- self . sess ,
1049+ let feature = if let Some ( feature) = lint_id. lint . feature_gate
1050+ && !self . features . active ( feature)
1051+ {
1052+ // Lint is behind a feature that is not enabled; eventually return false.
1053+ feature
1054+ } else {
1055+ // Lint is ungated or its feature is enabled; exit early.
1056+ return true ;
1057+ } ;
1058+
1059+ if self . lint_added_lints {
1060+ let lint = builtin:: UNKNOWN_LINTS ;
1061+ let ( level, src) = self . lint_level ( builtin:: UNKNOWN_LINTS ) ;
1062+ // FIXME: make this translatable
1063+ #[ allow( rustc:: diagnostic_outside_of_impl) ]
1064+ #[ allow( rustc:: untranslatable_diagnostic) ]
1065+ lint_level (
1066+ self . sess ,
1067+ lint,
1068+ level,
1069+ src,
1070+ Some ( span. into ( ) ) ,
1071+ fluent:: lint_unknown_gated_lint,
1072+ |lint| {
1073+ lint. arg ( "name" , lint_id. lint . name_lower ( ) ) ;
1074+ lint. note ( fluent:: lint_note) ;
1075+ rustc_session:: parse:: add_feature_diagnostics_for_issue (
10721076 lint,
1073- level,
1074- src,
1075- Some ( span. into ( ) ) ,
1076- fluent:: lint_unknown_gated_lint,
1077- |lint| {
1078- lint. arg ( "name" , lint_id. lint . name_lower ( ) ) ;
1079- lint. note ( fluent:: lint_note) ;
1080- rustc_session:: parse:: add_feature_diagnostics_for_issue (
1081- lint,
1082- & self . sess ,
1083- feature,
1084- GateIssue :: Language ,
1085- lint_from_cli,
1086- ) ;
1087- } ,
1077+ & self . sess ,
1078+ feature,
1079+ GateIssue :: Language ,
1080+ lint_from_cli,
10881081 ) ;
1089- }
1090- return false ;
1091- }
1082+ } ,
1083+ ) ;
10921084 }
1093- true
1085+
1086+ false
10941087 }
10951088
10961089 /// Find the lint level for a lint.
0 commit comments