@@ -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.
@@ -643,63 +644,61 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
643
644
//
644
645
// This means that this only errors if we're truly lowering the lint
645
646
// 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 {
679
689
overruled : src. span ( ) ,
680
690
lint_level : level. as_str ( ) ,
681
691
lint_source : src. name ( ) ,
682
692
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
+ }
696
696
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 ;
703
702
}
704
703
}
705
704
@@ -770,15 +769,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
770
769
771
770
let Some ( mut metas) = attr. meta_item_list ( ) else { continue } ;
772
771
773
- if metas. is_empty ( ) {
772
+ // Check whether `metas` is empty, and get its last element.
773
+ let Some ( tail_li) = metas. last ( ) else {
774
774
// This emits the unused_attributes lint for `#[level()]`
775
775
continue ;
776
- }
776
+ } ;
777
777
778
778
// Before processing the lint names, look for a reason (RFC 2383)
779
779
// at the end.
780
780
let mut reason = None ;
781
- let tail_li = & metas[ metas. len ( ) - 1 ] ;
782
781
if let Some ( item) = tail_li. meta_item ( ) {
783
782
match item. kind {
784
783
ast:: MetaItemKind :: Word => { } // actual lint names handled later
@@ -834,21 +833,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
834
833
let meta_item = match li {
835
834
ast:: NestedMetaItem :: MetaItem ( meta_item) if meta_item. is_word ( ) => meta_item,
836
835
_ => {
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 } ) ;
852
846
continue ;
853
847
}
854
848
} ;
@@ -987,11 +981,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
987
981
}
988
982
989
983
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) ;
995
985
let suggestion = suggestion. map ( |( replace, from_rustc) | {
996
986
UnknownLintSuggestion :: WithSpan { suggestion : sp, replace, from_rustc }
997
987
} ) ;
@@ -1005,27 +995,24 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
1005
995
if let CheckLintNameResult :: Renamed ( new_name) = lint_result {
1006
996
// Ignore any errors or warnings that happen because the new name is inaccurate
1007
997
// 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) =
1009
999
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 {
1028
1001
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
+ ) ;
1029
1016
}
1030
1017
}
1031
1018
}
@@ -1058,38 +1045,44 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
1058
1045
/// Returns `true` if the lint's feature is enabled.
1059
1046
#[ track_caller]
1060
1047
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 (
1071
1075
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,
1087
1080
) ;
1088
- }
1089
- return false ;
1090
- }
1081
+ } ,
1082
+ ) ;
1091
1083
}
1092
- true
1084
+
1085
+ false
1093
1086
}
1094
1087
1095
1088
/// Find the lint level for a lint.
0 commit comments