@@ -67,9 +67,10 @@ pub struct LintStore {
6767 /// Lints indexed by name.
6868 by_name : FxHashMap < String , TargetLint > ,
6969
70- /// Map of registered lint groups to what lints they expand to. The bool
71- /// is true if the lint group was added by a plugin.
72- lint_groups : FxHashMap < & ' static str , ( Vec < LintId > , bool ) > ,
70+ /// Map of registered lint groups to what lints they expand to. The first
71+ /// bool is true if the lint group was added by a plugin. The optional string
72+ /// is used to store the new names of deprecated lint group names.
73+ lint_groups : FxHashMap < & ' static str , ( Vec < LintId > , bool , Option < & ' static str > ) > ,
7374
7475 /// Extra info for future incompatibility lints, describing the
7576 /// issue or RFC that caused the incompatibility.
@@ -138,7 +139,7 @@ pub enum CheckLintNameResult<'a> {
138139 /// compiled with the tool and therefore the lint was never
139140 /// added to the `LintStore`. Otherwise the `LintId` will be
140141 /// returned as if it where a rustc lint.
141- Tool ( Option < & ' a [ LintId ] > ) ,
142+ Tool ( Result < & ' a [ LintId ] , ( Option < & ' a [ LintId ] > , String ) > ) ,
142143}
143144
144145impl LintStore {
@@ -221,7 +222,7 @@ impl LintStore {
221222 let lints = lints. iter ( ) . filter ( |f| f. edition == Some ( * edition) ) . map ( |f| f. id )
222223 . collect :: < Vec < _ > > ( ) ;
223224 if !lints. is_empty ( ) {
224- self . register_group ( sess, false , edition. lint_name ( ) , lints)
225+ self . register_group ( sess, false , edition. lint_name ( ) , None , lints)
225226 }
226227 }
227228
@@ -231,19 +232,35 @@ impl LintStore {
231232 self . future_incompatible . insert ( lint. id , lint) ;
232233 }
233234
234- self . register_group ( sess, false , "future_incompatible" , future_incompatible) ;
235-
236-
235+ self . register_group (
236+ sess,
237+ false ,
238+ "future_incompatible" ,
239+ None ,
240+ future_incompatible,
241+ ) ;
237242 }
238243
239244 pub fn future_incompatible ( & self , id : LintId ) -> Option < & FutureIncompatibleInfo > {
240245 self . future_incompatible . get ( & id)
241246 }
242247
243- pub fn register_group ( & mut self , sess : Option < & Session > ,
244- from_plugin : bool , name : & ' static str ,
245- to : Vec < LintId > ) {
246- let new = self . lint_groups . insert ( name, ( to, from_plugin) ) . is_none ( ) ;
248+ pub fn register_group (
249+ & mut self ,
250+ sess : Option < & Session > ,
251+ from_plugin : bool ,
252+ name : & ' static str ,
253+ deprecated_name : Option < & ' static str > ,
254+ to : Vec < LintId > ,
255+ ) {
256+ let new = self
257+ . lint_groups
258+ . insert ( name, ( to, from_plugin, None ) )
259+ . is_none ( ) ;
260+ if let Some ( deprecated) = deprecated_name {
261+ self . lint_groups
262+ . insert ( deprecated, ( vec ! [ ] , from_plugin, Some ( name) ) ) ;
263+ }
247264
248265 if !new {
249266 let msg = format ! ( "duplicate specification of lint group {}" , name) ;
@@ -336,34 +353,79 @@ impl LintStore {
336353 } else {
337354 lint_name. to_string ( )
338355 } ;
356+ // If the lint was scoped with `tool::` check if the tool lint exists
339357 if let Some ( _) = tool_name {
340358 match self . by_name . get ( & complete_name) {
341359 None => match self . lint_groups . get ( & * complete_name) {
342- None => return CheckLintNameResult :: Tool ( None ) ,
343- Some ( ids) => return CheckLintNameResult :: Tool ( Some ( & ids. 0 ) ) ,
360+ None => return CheckLintNameResult :: Tool ( Err ( ( None , String :: new ( ) ) ) ) ,
361+ Some ( ids) => return CheckLintNameResult :: Tool ( Ok ( & ids. 0 ) ) ,
344362 } ,
345- Some ( & Id ( ref id) ) => return CheckLintNameResult :: Tool ( Some ( slice:: from_ref ( id) ) ) ,
363+ Some ( & Id ( ref id) ) => return CheckLintNameResult :: Tool ( Ok ( slice:: from_ref ( id) ) ) ,
346364 // If the lint was registered as removed or renamed by the lint tool, we don't need
347365 // to treat tool_lints and rustc lints different and can use the code below.
348366 _ => { }
349367 }
350368 }
351369 match self . by_name . get ( & complete_name) {
352370 Some ( & Renamed ( ref new_name, _) ) => CheckLintNameResult :: Warning (
353- format ! ( "lint `{}` has been renamed to `{}`" , lint_name, new_name) ,
371+ format ! (
372+ "lint `{}` has been renamed to `{}`" ,
373+ complete_name, new_name
374+ ) ,
354375 Some ( new_name. to_owned ( ) ) ,
355376 ) ,
356377 Some ( & Removed ( ref reason) ) => CheckLintNameResult :: Warning (
357- format ! ( "lint `{}` has been removed: `{}`" , lint_name , reason) ,
378+ format ! ( "lint `{}` has been removed: `{}`" , complete_name , reason) ,
358379 None ,
359380 ) ,
360381 None => match self . lint_groups . get ( & * complete_name) {
361- None => CheckLintNameResult :: NoLint ,
362- Some ( ids) => CheckLintNameResult :: Ok ( & ids. 0 ) ,
382+ // If neither the lint, nor the lint group exists check if there is a `clippy::`
383+ // variant of this lint
384+ None => self . check_tool_name_for_backwards_compat ( & complete_name, "clippy" ) ,
385+ Some ( ids) => {
386+ // Check if the lint group name is deprecated
387+ if let Some ( new_name) = ids. 2 {
388+ let lint_ids = self . lint_groups . get ( new_name) . unwrap ( ) ;
389+ return CheckLintNameResult :: Tool ( Err ( (
390+ Some ( & lint_ids. 0 ) ,
391+ new_name. to_string ( ) ,
392+ ) ) ) ;
393+ }
394+ CheckLintNameResult :: Ok ( & ids. 0 )
395+ }
363396 } ,
364397 Some ( & Id ( ref id) ) => CheckLintNameResult :: Ok ( slice:: from_ref ( id) ) ,
365398 }
366399 }
400+
401+ fn check_tool_name_for_backwards_compat (
402+ & self ,
403+ lint_name : & str ,
404+ tool_name : & str ,
405+ ) -> CheckLintNameResult {
406+ let complete_name = format ! ( "{}::{}" , tool_name, lint_name) ;
407+ match self . by_name . get ( & complete_name) {
408+ None => match self . lint_groups . get ( & * complete_name) {
409+ // Now we are sure, that this lint exists nowhere
410+ None => CheckLintNameResult :: NoLint ,
411+ Some ( ids) => {
412+ // Reaching this would be weird, but lets cover this case anyway
413+ if let Some ( new_name) = ids. 2 {
414+ let lint_ids = self . lint_groups . get ( new_name) . unwrap ( ) ;
415+ return CheckLintNameResult :: Tool ( Err ( (
416+ Some ( & lint_ids. 0 ) ,
417+ new_name. to_string ( ) ,
418+ ) ) ) ;
419+ }
420+ CheckLintNameResult :: Tool ( Err ( ( Some ( & ids. 0 ) , complete_name) ) )
421+ }
422+ } ,
423+ Some ( & Id ( ref id) ) => {
424+ CheckLintNameResult :: Tool ( Err ( ( Some ( slice:: from_ref ( id) ) , complete_name) ) )
425+ }
426+ _ => CheckLintNameResult :: NoLint ,
427+ }
428+ }
367429}
368430
369431/// Context for lint checking after type checking.
0 commit comments