11use super :: { Attribute , DEPRECATED_CFG_ATTR , DEPRECATED_CLIPPY_CFG_ATTR , unnecessary_clippy_cfg} ;
2- use clippy_utils:: diagnostics:: span_lint_and_sugg;
2+ use clippy_utils:: diagnostics:: { span_lint_and_sugg, span_lint_and_then , span_lint_hir_and_then } ;
33use clippy_utils:: msrvs:: { self , MsrvStack } ;
44use clippy_utils:: sym;
55use rustc_ast:: AttrStyle ;
66use rustc_errors:: Applicability ;
7- use rustc_lint:: EarlyContext ;
7+ use rustc_hir:: attrs:: CfgEntry ;
8+ use rustc_hir:: def_id:: { LOCAL_CRATE , LocalDefId } ;
9+ use rustc_lint:: { EarlyContext , LateContext } ;
810
9- pub ( super ) fn check ( cx : & EarlyContext < ' _ > , attr : & Attribute , msrv : & MsrvStack ) {
11+ pub ( super ) fn check_cfg_attr ( cx : & EarlyContext < ' _ > , attr : & Attribute , msrv : & MsrvStack ) {
1012 // check cfg_attr
11- if attr. has_name ( sym:: cfg_attr )
13+ if attr. has_name ( sym:: cfg_attr_trace )
1214 && let Some ( items) = attr. meta_item_list ( )
1315 && items. len ( ) == 2
1416 && let Some ( feature_item) = items[ 0 ] . meta_item ( )
@@ -27,18 +29,23 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
2729 . ident
2830 . name
2931 == sym:: skip)
30- // Only lint outer attributes, because custom inner attributes are unstable
31- // Tracking issue: https://github.com/rust-lang/rust/issues/54726
32- && attr. style == AttrStyle :: Outer
3332 {
34- span_lint_and_sugg (
33+ span_lint_and_then (
3534 cx,
3635 DEPRECATED_CFG_ATTR ,
3736 attr. span ,
38- "`cfg_attr` is deprecated for rustfmt and got replaced by tool attributes" ,
39- "use" ,
40- "#[rustfmt::skip]" . to_string ( ) ,
41- Applicability :: MachineApplicable ,
37+ "`cfg_attr` is deprecated for rustfmt" ,
38+ |diag| {
39+ diag. span_suggestion_verbose (
40+ attr. span ,
41+ "use the `rustfmt::skip` tool attribute instead" ,
42+ match attr. style {
43+ AttrStyle :: Outer => "#[rustfmt::skip]" ,
44+ AttrStyle :: Inner => "#![rustfmt::skip]" ,
45+ } ,
46+ Applicability :: MaybeIncorrect , // See Known Problems
47+ ) ;
48+ } ,
4249 ) ;
4350 } else {
4451 check_deprecated_cfg_recursively ( cx, feature_item) ;
@@ -49,8 +56,8 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &MsrvStack) {
4956 }
5057}
5158
52- pub ( super ) fn check_clippy ( cx : & EarlyContext < ' _ > , attr : & Attribute ) {
53- if attr. has_name ( sym:: cfg )
59+ pub ( super ) fn check_cfg ( cx : & EarlyContext < ' _ > , attr : & Attribute ) {
60+ if attr. has_name ( sym:: cfg_trace )
5461 && let Some ( list) = attr. meta_item_list ( )
5562 {
5663 for item in list. iter ( ) . filter_map ( |item| item. meta_item ( ) ) {
@@ -85,3 +92,40 @@ fn check_cargo_clippy_attr(cx: &EarlyContext<'_>, item: &rustc_ast::MetaItem) {
8592 ) ;
8693 }
8794}
95+
96+ pub fn check_stripped ( cx : & LateContext < ' _ > ) {
97+ for stripped in cx. tcx . stripped_cfg_items ( LOCAL_CRATE ) {
98+ if let Some ( parent_module) = stripped. parent_module . as_local ( ) {
99+ check_cfg_entry ( cx, & stripped. cfg . 0 , parent_module) ;
100+ }
101+ }
102+ }
103+
104+ fn check_cfg_entry ( cx : & LateContext < ' _ > , cfg : & CfgEntry , parent_module : LocalDefId ) {
105+ match cfg {
106+ & CfgEntry :: NameValue {
107+ name : sym:: feature,
108+ name_span : _,
109+ value : Some ( ( sym:: cargo_clippy, _) ) ,
110+ span,
111+ } => {
112+ span_lint_hir_and_then (
113+ cx,
114+ DEPRECATED_CLIPPY_CFG_ATTR ,
115+ cx. tcx . local_def_id_to_hir_id ( parent_module) ,
116+ span,
117+ "`feature = \" cargo-clippy\" ` was replaced by `clippy`" ,
118+ |diag| {
119+ diag. span_suggestion ( span, "replace with" , "clippy" , Applicability :: MachineApplicable ) ;
120+ } ,
121+ ) ;
122+ } ,
123+ CfgEntry :: All ( children, _) | CfgEntry :: Any ( children, _) => {
124+ for child in children {
125+ check_cfg_entry ( cx, child, parent_module) ;
126+ }
127+ } ,
128+ CfgEntry :: Not ( child, _) => check_cfg_entry ( cx, child, parent_module) ,
129+ _ => { } ,
130+ }
131+ }
0 commit comments