Skip to content

Commit a770d8e

Browse files
committed
Differ between inner and outer attributes
1 parent 7bd8c30 commit a770d8e

File tree

1 file changed

+48
-5
lines changed

1 file changed

+48
-5
lines changed

clippy_lints/src/attrs.rs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)