@@ -103,11 +103,12 @@ impl LintLevelSets {
103
103
mut idx : LintStackIndex ,
104
104
aux : Option < & FxIndexMap < LintId , LevelAndSource > > ,
105
105
) -> ( 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 ) ;
110
110
}
111
+
111
112
loop {
112
113
let LintSet { ref specs, parent } = self . list [ idx] ;
113
114
if let Some ( & ( level, src) ) = specs. get ( & id) {
@@ -177,7 +178,7 @@ fn shallow_lint_levels_on(tcx: TyCtxt<'_>, owner: hir::OwnerId) -> ShallowLintLe
177
178
// There is only something to do if there are attributes at all.
178
179
[ ] => { }
179
180
// 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 } ) ,
181
182
// Otherwise, we need to visit the attributes in source code order, so we fetch HIR and do
182
183
// a standard visit.
183
184
// FIXME(#102522) Just iterate on attrs once that iteration order matches HIR's.
@@ -644,63 +645,61 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
644
645
//
645
646
// This means that this only errors if we're truly lowering the lint
646
647
// 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 {
680
690
overruled : src. span ( ) ,
681
691
lint_level : level. as_str ( ) ,
682
692
lint_source : src. name ( ) ,
683
693
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
+ }
697
697
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 ;
704
703
}
705
704
}
706
705
@@ -771,15 +770,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
771
770
772
771
let Some ( mut metas) = attr. meta_item_list ( ) else { continue } ;
773
772
774
- if metas. is_empty ( ) {
773
+ // Check whether `metas` is empty, and get its last element.
774
+ let Some ( tail_li) = metas. last ( ) else {
775
775
// This emits the unused_attributes lint for `#[level()]`
776
776
continue ;
777
- }
777
+ } ;
778
778
779
779
// Before processing the lint names, look for a reason (RFC 2383)
780
780
// at the end.
781
781
let mut reason = None ;
782
- let tail_li = & metas[ metas. len ( ) - 1 ] ;
783
782
if let Some ( item) = tail_li. meta_item ( ) {
784
783
match item. kind {
785
784
ast:: MetaItemKind :: Word => { } // actual lint names handled later
@@ -835,21 +834,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
835
834
let meta_item = match li {
836
835
ast:: NestedMetaItem :: MetaItem ( meta_item) if meta_item. is_word ( ) => meta_item,
837
836
_ => {
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 } ) ;
853
847
continue ;
854
848
}
855
849
} ;
@@ -988,11 +982,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
988
982
}
989
983
990
984
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) ;
996
986
let suggestion = suggestion. map ( |( replace, from_rustc) | {
997
987
UnknownLintSuggestion :: WithSpan { suggestion : sp, replace, from_rustc }
998
988
} ) ;
@@ -1006,27 +996,24 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
1006
996
if let CheckLintNameResult :: Renamed ( new_name) = lint_result {
1007
997
// Ignore any errors or warnings that happen because the new name is inaccurate
1008
998
// 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) =
1010
1000
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 {
1029
1002
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
+ ) ;
1030
1017
}
1031
1018
}
1032
1019
}
@@ -1059,38 +1046,44 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
1059
1046
/// Returns `true` if the lint's feature is enabled.
1060
1047
#[ track_caller]
1061
1048
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 (
1072
1076
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,
1088
1081
) ;
1089
- }
1090
- return false ;
1091
- }
1082
+ } ,
1083
+ ) ;
1092
1084
}
1093
- true
1085
+
1086
+ false
1094
1087
}
1095
1088
1096
1089
/// Find the lint level for a lint.
0 commit comments