@@ -67,9 +67,10 @@ pub struct LintStore {
67
67
/// Lints indexed by name.
68
68
by_name : FxHashMap < String , TargetLint > ,
69
69
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 > ) > ,
73
74
74
75
/// Extra info for future incompatibility lints, describing the
75
76
/// issue or RFC that caused the incompatibility.
@@ -138,7 +139,7 @@ pub enum CheckLintNameResult<'a> {
138
139
/// compiled with the tool and therefore the lint was never
139
140
/// added to the `LintStore`. Otherwise the `LintId` will be
140
141
/// returned as if it where a rustc lint.
141
- Tool ( Option < & ' a [ LintId ] > ) ,
142
+ Tool ( Result < & ' a [ LintId ] , ( Option < & ' a [ LintId ] > , String ) > ) ,
142
143
}
143
144
144
145
impl LintStore {
@@ -221,7 +222,7 @@ impl LintStore {
221
222
let lints = lints. iter ( ) . filter ( |f| f. edition == Some ( * edition) ) . map ( |f| f. id )
222
223
. collect :: < Vec < _ > > ( ) ;
223
224
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)
225
226
}
226
227
}
227
228
@@ -231,19 +232,35 @@ impl LintStore {
231
232
self . future_incompatible . insert ( lint. id , lint) ;
232
233
}
233
234
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
+ ) ;
237
242
}
238
243
239
244
pub fn future_incompatible ( & self , id : LintId ) -> Option < & FutureIncompatibleInfo > {
240
245
self . future_incompatible . get ( & id)
241
246
}
242
247
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
+ }
247
264
248
265
if !new {
249
266
let msg = format ! ( "duplicate specification of lint group {}" , name) ;
@@ -336,34 +353,79 @@ impl LintStore {
336
353
} else {
337
354
lint_name. to_string ( )
338
355
} ;
356
+ // If the lint was scoped with `tool::` check if the tool lint exists
339
357
if let Some ( _) = tool_name {
340
358
match self . by_name . get ( & complete_name) {
341
359
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 ) ) ,
344
362
} ,
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) ) ) ,
346
364
// If the lint was registered as removed or renamed by the lint tool, we don't need
347
365
// to treat tool_lints and rustc lints different and can use the code below.
348
366
_ => { }
349
367
}
350
368
}
351
369
match self . by_name . get ( & complete_name) {
352
370
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
+ ) ,
354
375
Some ( new_name. to_owned ( ) ) ,
355
376
) ,
356
377
Some ( & Removed ( ref reason) ) => CheckLintNameResult :: Warning (
357
- format ! ( "lint `{}` has been removed: `{}`" , lint_name , reason) ,
378
+ format ! ( "lint `{}` has been removed: `{}`" , complete_name , reason) ,
358
379
None ,
359
380
) ,
360
381
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
+ }
363
396
} ,
364
397
Some ( & Id ( ref id) ) => CheckLintNameResult :: Ok ( slice:: from_ref ( id) ) ,
365
398
}
366
399
}
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
+ }
367
429
}
368
430
369
431
/// Context for lint checking after type checking.
0 commit comments