1+ use crate :: errors:: { CheckNameUnknownTool , RequestedLevel , UnsupportedGroup } ;
2+ use crate :: lints:: {
3+ DeprecatedLintNameFromCommandLine , RemovedLintFromCommandLine , RenamedLintFromCommandLine ,
4+ UnknownLintFromCommandLine ,
5+ } ;
16use crate :: {
27 builtin:: MISSING_DOCS ,
38 context:: { CheckLintNameResult , LintStore } ,
@@ -552,12 +557,55 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
552557
553558 fn add_command_line ( & mut self ) {
554559 for & ( ref lint_name, level) in & self . sess . opts . lint_opts {
555- self . store . check_lint_name_cmdline ( self . sess , & lint_name, level, self . registered_tools ) ;
560+ // Checks the validity of lint names derived from the command line.
561+ let ( tool_name, lint_name_only) = parse_lint_and_tool_name ( lint_name) ;
562+ if lint_name_only == crate :: WARNINGS . name_lower ( )
563+ && matches ! ( level, Level :: ForceWarn ( _) )
564+ {
565+ self . sess . emit_err ( UnsupportedGroup { lint_group : crate :: WARNINGS . name_lower ( ) } ) ;
566+ }
567+ match self . store . check_lint_name ( lint_name_only, tool_name, self . registered_tools ) {
568+ CheckLintNameResult :: Renamed ( ref replace) => {
569+ let name = lint_name. as_str ( ) ;
570+ let suggestion = RenamedLintSuggestion :: WithoutSpan { replace } ;
571+ let requested_level = RequestedLevel { level, lint_name } ;
572+ let lint = RenamedLintFromCommandLine { name, suggestion, requested_level } ;
573+ self . emit_lint ( RENAMED_AND_REMOVED_LINTS , lint) ;
574+ }
575+ CheckLintNameResult :: Removed ( ref reason) => {
576+ let name = lint_name. as_str ( ) ;
577+ let requested_level = RequestedLevel { level, lint_name } ;
578+ let lint = RemovedLintFromCommandLine { name, reason, requested_level } ;
579+ self . emit_lint ( RENAMED_AND_REMOVED_LINTS , lint) ;
580+ }
581+ CheckLintNameResult :: NoLint ( suggestion) => {
582+ let name = lint_name. clone ( ) ;
583+ let suggestion =
584+ suggestion. map ( |replace| UnknownLintSuggestion :: WithoutSpan { replace } ) ;
585+ let requested_level = RequestedLevel { level, lint_name } ;
586+ let lint = UnknownLintFromCommandLine { name, suggestion, requested_level } ;
587+ self . emit_lint ( UNKNOWN_LINTS , lint) ;
588+ }
589+ CheckLintNameResult :: Tool ( Err ( ( Some ( _) , ref replace) ) ) => {
590+ let name = lint_name. clone ( ) ;
591+ let requested_level = RequestedLevel { level, lint_name } ;
592+ let lint = DeprecatedLintNameFromCommandLine { name, replace, requested_level } ;
593+ self . emit_lint ( RENAMED_AND_REMOVED_LINTS , lint) ;
594+ }
595+ CheckLintNameResult :: NoTool => {
596+ self . sess . emit_err ( CheckNameUnknownTool {
597+ tool_name : tool_name. unwrap ( ) ,
598+ sub : RequestedLevel { level, lint_name } ,
599+ } ) ;
600+ }
601+ _ => { }
602+ } ;
603+
556604 let orig_level = level;
557605 let lint_flag_val = Symbol :: intern ( lint_name) ;
558606
559607 let Ok ( ids) = self . store . find_lints ( & lint_name) else {
560- // errors handled in check_lint_name_cmdline above
608+ // errors already handled above
561609 continue ;
562610 } ;
563611 for id in ids {
@@ -915,24 +963,18 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
915963
916964 _ if !self . warn_about_weird_lints => { }
917965
918- CheckLintNameResult :: Renamed ( new_name ) => {
966+ CheckLintNameResult :: Renamed ( ref replace ) => {
919967 let suggestion =
920- RenamedLintSuggestion { suggestion : sp, replace : new_name . as_str ( ) } ;
968+ RenamedLintSuggestion :: WithSpan { suggestion : sp, replace } ;
921969 let name = tool_ident. map ( |tool| format ! ( "{tool}::{name}" ) ) . unwrap_or ( name) ;
922- self . emit_spanned_lint (
923- RENAMED_AND_REMOVED_LINTS ,
924- sp. into ( ) ,
925- RenamedLint { name : name. as_str ( ) , suggestion } ,
926- ) ;
970+ let lint = RenamedLint { name : name. as_str ( ) , suggestion } ;
971+ self . emit_spanned_lint ( RENAMED_AND_REMOVED_LINTS , sp. into ( ) , lint) ;
927972 }
928973
929- CheckLintNameResult :: Removed ( reason) => {
974+ CheckLintNameResult :: Removed ( ref reason) => {
930975 let name = tool_ident. map ( |tool| format ! ( "{tool}::{name}" ) ) . unwrap_or ( name) ;
931- self . emit_spanned_lint (
932- RENAMED_AND_REMOVED_LINTS ,
933- sp. into ( ) ,
934- RemovedLint { name : name. as_str ( ) , reason : reason. as_str ( ) } ,
935- ) ;
976+ let lint = RemovedLint { name : name. as_str ( ) , reason } ;
977+ self . emit_spanned_lint ( RENAMED_AND_REMOVED_LINTS , sp. into ( ) , lint) ;
936978 }
937979
938980 CheckLintNameResult :: NoLint ( suggestion) => {
@@ -941,13 +983,11 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
941983 } else {
942984 name. to_string ( )
943985 } ;
944- let suggestion = suggestion
945- . map ( |replace| UnknownLintSuggestion { suggestion : sp, replace } ) ;
946- self . emit_spanned_lint (
947- UNKNOWN_LINTS ,
948- sp. into ( ) ,
949- UnknownLint { name, suggestion } ,
950- ) ;
986+ let suggestion = suggestion. map ( |replace| {
987+ UnknownLintSuggestion :: WithSpan { suggestion : sp, replace }
988+ } ) ;
989+ let lint = UnknownLint { name, suggestion } ;
990+ self . emit_spanned_lint ( UNKNOWN_LINTS , sp. into ( ) , lint) ;
951991 }
952992 }
953993 // If this lint was renamed, apply the new lint instead of ignoring the attribute.
@@ -1092,3 +1132,14 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
10921132pub ( crate ) fn provide ( providers : & mut Providers ) {
10931133 * providers = Providers { shallow_lint_levels_on, lint_expectations, ..* providers } ;
10941134}
1135+
1136+ pub fn parse_lint_and_tool_name ( lint_name : & str ) -> ( Option < Symbol > , & str ) {
1137+ match lint_name. split_once ( "::" ) {
1138+ Some ( ( tool_name, lint_name) ) => {
1139+ let tool_name = Symbol :: intern ( tool_name) ;
1140+
1141+ ( Some ( tool_name) , lint_name)
1142+ }
1143+ None => ( None , lint_name) ,
1144+ }
1145+ }
0 commit comments