@@ -37,10 +37,28 @@ const BLACK_LISTED_LINTS: [&str; 3] = ["lint_author", "deep_code_inspection", "i
37
37
/// These groups will be ignored by the lint group matcher. This is useful for collections like
38
38
/// `clippy::all`
39
39
const IGNORED_LINT_GROUPS : [ & str ; 1 ] = [ "clippy::all" ] ;
40
- /// Lints within this group will be excluded from the collection
41
- const EXCLUDED_LINT_GROUPS : [ & str ; 1 ] = [ "clippy::internal" ] ;
40
+ /// Lints within this group will be excluded from the collection. These groups
41
+ /// have to be defined without the `clippy::` prefix.
42
+ const EXCLUDED_LINT_GROUPS : [ & str ; 1 ] = [ "internal" ] ;
42
43
/// Collected deprecated lint will be assigned to this group in the JSON output
43
- const DEPRECATED_LINT_GROUP_STR : & str = "DEPRECATED" ;
44
+ const DEPRECATED_LINT_GROUP_STR : & str = "deprecated" ;
45
+ /// This is the lint level for deprecated lints that will be displayed in the lint list
46
+ const DEPRECATED_LINT_LEVEL : & str = "none" ;
47
+ /// This array holds Clippy's lint groups with their corresponding default lint level. The
48
+ /// lint level for deprecated lints is set in `DEPRECATED_LINT_LEVEL`.
49
+ const DEFAULT_LINT_LEVELS : [ ( & str , & str ) ; 8 ] = [
50
+ ( "correctness" , "deny" ) ,
51
+ ( "restriction" , "allow" ) ,
52
+ ( "style" , "warn" ) ,
53
+ ( "pedantic" , "allow" ) ,
54
+ ( "complexity" , "warn" ) ,
55
+ ( "perf" , "warn" ) ,
56
+ ( "cargo" , "allow" ) ,
57
+ ( "nursery" , "allow" ) ,
58
+ ] ;
59
+ /// This prefix is in front of the lint groups in the lint store. The prefix will be trimmed
60
+ /// to only keep the actual lint group in the output.
61
+ const CLIPPY_LINT_GROUP_PREFIX : & str = "clippy::" ;
44
62
45
63
/// This template will be used to format the configuration section in the lint documentation.
46
64
/// The `configurations` parameter will be replaced with one or multiple formatted
@@ -188,18 +206,20 @@ struct LintMetadata {
188
206
id : String ,
189
207
id_span : SerializableSpan ,
190
208
group : String ,
209
+ level : & ' static str ,
191
210
docs : String ,
192
211
/// This field is only used in the output and will only be
193
212
/// mapped shortly before the actual output.
194
213
applicability : Option < ApplicabilityInfo > ,
195
214
}
196
215
197
216
impl LintMetadata {
198
- fn new ( id : String , id_span : SerializableSpan , group : String , docs : String ) -> Self {
217
+ fn new ( id : String , id_span : SerializableSpan , group : String , level : & ' static str , docs : String ) -> Self {
199
218
Self {
200
219
id,
201
220
id_span,
202
221
group,
222
+ level,
203
223
docs,
204
224
applicability : None ,
205
225
}
@@ -368,7 +388,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
368
388
let lint_name = sym_to_string( item. ident. name) . to_ascii_lowercase( ) ;
369
389
if !BLACK_LISTED_LINTS . contains( & lint_name. as_str( ) ) ;
370
390
// metadata extraction
371
- if let Some ( group) = get_lint_group_or_lint ( cx, & lint_name, item) ;
391
+ if let Some ( ( group, level ) ) = get_lint_group_and_level_or_lint ( cx, & lint_name, item) ;
372
392
if let Some ( mut docs) = extract_attr_docs_or_lint( cx, item) ;
373
393
then {
374
394
if let Some ( configuration_section) = self . get_lint_configs( & lint_name) {
@@ -379,6 +399,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
379
399
lint_name,
380
400
SerializableSpan :: from_item( cx, item) ,
381
401
group,
402
+ level,
382
403
docs,
383
404
) ) ;
384
405
}
@@ -396,6 +417,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
396
417
lint_name,
397
418
SerializableSpan :: from_item( cx, item) ,
398
419
DEPRECATED_LINT_GROUP_STR . to_string( ) ,
420
+ DEPRECATED_LINT_LEVEL ,
399
421
docs,
400
422
) ) ;
401
423
}
@@ -475,15 +497,32 @@ fn extract_attr_docs(cx: &LateContext<'_>, item: &Item<'_>) -> Option<String> {
475
497
} )
476
498
}
477
499
478
- fn get_lint_group_or_lint ( cx : & LateContext < ' _ > , lint_name : & str , item : & ' hir Item < ' _ > ) -> Option < String > {
500
+ fn get_lint_group_and_level_or_lint (
501
+ cx : & LateContext < ' _ > ,
502
+ lint_name : & str ,
503
+ item : & ' hir Item < ' _ > ,
504
+ ) -> Option < ( String , & ' static str ) > {
479
505
let result = cx. lint_store . check_lint_name ( lint_name, Some ( sym:: clippy) ) ;
480
506
if let CheckLintNameResult :: Tool ( Ok ( lint_lst) ) = result {
481
- get_lint_group ( cx, lint_lst[ 0 ] )
482
- . or_else ( || {
483
- lint_collection_error_item ( cx, item, "Unable to determine lint group" ) ;
507
+ if let Some ( group) = get_lint_group ( cx, lint_lst[ 0 ] ) {
508
+ if EXCLUDED_LINT_GROUPS . contains ( & group. as_str ( ) ) {
509
+ return None ;
510
+ }
511
+
512
+ if let Some ( level) = get_lint_level_from_group ( & group) {
513
+ Some ( ( group, level) )
514
+ } else {
515
+ lint_collection_error_item (
516
+ cx,
517
+ item,
518
+ & format ! ( "Unable to determine lint level for found group `{}`" , group) ,
519
+ ) ;
484
520
None
485
- } )
486
- . filter ( |group| !EXCLUDED_LINT_GROUPS . contains ( & group. as_str ( ) ) )
521
+ }
522
+ } else {
523
+ lint_collection_error_item ( cx, item, "Unable to determine lint group" ) ;
524
+ None
525
+ }
487
526
} else {
488
527
lint_collection_error_item ( cx, item, "Unable to find lint in lint_store" ) ;
489
528
None
@@ -496,14 +535,21 @@ fn get_lint_group(cx: &LateContext<'_>, lint_id: LintId) -> Option<String> {
496
535
continue ;
497
536
}
498
537
499
- if lints. iter ( ) . any ( |x| * x == lint_id) {
500
- return Some ( ( * group_name) . to_string ( ) ) ;
538
+ if lints. iter ( ) . any ( |group_lint| * group_lint == lint_id) {
539
+ let group = group_name. strip_prefix ( CLIPPY_LINT_GROUP_PREFIX ) . unwrap_or ( group_name) ;
540
+ return Some ( ( * group) . to_string ( ) ) ;
501
541
}
502
542
}
503
543
504
544
None
505
545
}
506
546
547
+ fn get_lint_level_from_group ( lint_group : & str ) -> Option < & ' static str > {
548
+ DEFAULT_LINT_LEVELS
549
+ . iter ( )
550
+ . find_map ( |( group_name, group_level) | ( * group_name == lint_group) . then ( || * group_level) )
551
+ }
552
+
507
553
fn is_deprecated_lint ( cx : & LateContext < ' _ > , ty : & hir:: Ty < ' _ > ) -> bool {
508
554
if let hir:: TyKind :: Path ( ref path) = ty. kind {
509
555
if let hir:: def:: Res :: Def ( DefKind :: Struct , def_id) = cx. qpath_res ( path, ty. hir_id ) {
0 commit comments