about summary refs log tree commit diff
diff options
context:
space:
mode:
authorflip1995 <9744647+flip1995@users.noreply.github.com>2018-09-18 11:35:53 +0200
committerflip1995 <hello@philkrones.com>2018-11-02 19:49:58 +0100
commita770d8edd0f5f6d1bc4b2abb0842f900f121c186 (patch)
tree791eafefcc0640c1a3e3ef5ef05925d57ec97a19
parent7bd8c303d34369124b6550ad6c645d2e1a149214 (diff)
downloadrust-a770d8edd0f5f6d1bc4b2abb0842f900f121c186.tar.gz
rust-a770d8edd0f5f6d1bc4b2abb0842f900f121c186.zip
Differ between inner and outer attributes
-rw-r--r--clippy_lints/src/attrs.rs53
1 files changed, 48 insertions, 5 deletions
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index 4ea13f649d7..24edf6d8495 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -172,12 +172,12 @@ declare_clippy_lint! {
 /// **What it does:** Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
 /// with `#[rustfmt::skip]`.
 ///
-/// **Why is this bad?** Since tool_attributes (rust-lang/rust#44690) are stable now, they should
-/// be used instead of the old `cfg_attr(rustfmt)` attribute.
+/// **Why is this bad?** Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
+/// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
 ///
-/// **Known problems:** It currently only detects outer attributes. But since it does not really
-/// makes sense to have `#![cfg_attr(rustfmt, rustfmt_skip)]` as an inner attribute, this should be
-/// ok.
+/// **Known problems:** This lint doesn't detect crate level inner attributes, because they get
+/// processed before the PreExpansionPass lints get executed. See
+/// [#3123](https://github.com/rust-lang-nursery/rust-clippy/pull/3123#issuecomment-422321765)
 ///
 /// **Example:**
 ///
@@ -495,3 +495,46 @@ fn is_present_in_source(cx: &LateContext<'_, '_>, span: Span) -> bool {
     }
     true
 }
+
+#[derive(Copy, Clone)]
+pub struct CfgAttrPass;
+
+impl LintPass for CfgAttrPass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(
+            DEPRECATED_CFG_ATTR,
+        )
+    }
+}
+
+impl EarlyLintPass for CfgAttrPass {
+    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
+        if_chain! {
+            // check cfg_attr
+            if attr.name() == "cfg_attr";
+            if let Some(ref items) = attr.meta_item_list();
+            if items.len() == 2;
+            // check for `rustfmt`
+            if let Some(feature_item) = items[0].meta_item();
+            if feature_item.name() == "rustfmt";
+            // check for `rustfmt_skip`
+            if let Some(skip_item) = &items[1].meta_item();
+            if skip_item.name() == "rustfmt_skip";
+            then {
+                let attr_style = match attr.style {
+                    AttrStyle::Outer => "#[",
+                    AttrStyle::Inner => "#![",
+                };
+                span_lint_and_sugg(
+                    cx,
+                    DEPRECATED_CFG_ATTR,
+                    attr.span,
+                    "`cfg_attr` is deprecated for rustfmt and got replaced by tool_attributes",
+                    "use",
+                    format!("{}rustfmt::skip]", attr_style),
+                );
+            }
+        }
+    }
+}
+