@@ -172,12 +172,12 @@ declare_clippy_lint! {
172172/// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
173173/// with `#[rustfmt::skip]`.
174174///
175- /// **Why is this bad?** Since tool_attributes (rust-lang/rust#44690) are stable now, they should
176- /// be used instead of the old `cfg_attr(rustfmt)` attribute .
175+ /// **Why is this bad?** Since tool_attributes ([ rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
176+ /// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes .
177177///
178- /// **Known problems:** It currently only detects outer attributes. But since it does not really
179- /// makes sense to have `#![cfg_attr(rustfmt, rustfmt_skip)]` as an inner attribute, this should be
180- /// ok.
178+ /// **Known problems:** This lint doesn't detect crate level inner attributes, because they get
179+ /// processed before the PreExpansionPass lints get executed. See
180+ /// [#3123](https://github.com/rust-lang-nursery/rust-clippy/pull/3123#issuecomment-422321765)
181181///
182182/// **Example:**
183183///
@@ -495,3 +495,46 @@ fn is_present_in_source(cx: &LateContext<'_, '_>, span: Span) -> bool {
495495 }
496496 true
497497}
498+
499+ #[ derive( Copy , Clone ) ]
500+ pub struct CfgAttrPass ;
501+
502+ impl LintPass for CfgAttrPass {
503+ fn get_lints ( & self ) -> LintArray {
504+ lint_array ! (
505+ DEPRECATED_CFG_ATTR ,
506+ )
507+ }
508+ }
509+
510+ impl EarlyLintPass for CfgAttrPass {
511+ fn check_attribute ( & mut self , cx : & EarlyContext < ' _ > , attr : & Attribute ) {
512+ if_chain ! {
513+ // check cfg_attr
514+ if attr. name( ) == "cfg_attr" ;
515+ if let Some ( ref items) = attr. meta_item_list( ) ;
516+ if items. len( ) == 2 ;
517+ // check for `rustfmt`
518+ if let Some ( feature_item) = items[ 0 ] . meta_item( ) ;
519+ if feature_item. name( ) == "rustfmt" ;
520+ // check for `rustfmt_skip`
521+ if let Some ( skip_item) = & items[ 1 ] . meta_item( ) ;
522+ if skip_item. name( ) == "rustfmt_skip" ;
523+ then {
524+ let attr_style = match attr. style {
525+ AttrStyle :: Outer => "#[" ,
526+ AttrStyle :: Inner => "#![" ,
527+ } ;
528+ span_lint_and_sugg(
529+ cx,
530+ DEPRECATED_CFG_ATTR ,
531+ attr. span,
532+ "`cfg_attr` is deprecated for rustfmt and got replaced by tool_attributes" ,
533+ "use" ,
534+ format!( "{}rustfmt::skip]" , attr_style) ,
535+ ) ;
536+ }
537+ }
538+ }
539+ }
540+
0 commit comments