about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-05-12 08:01:10 +0000
committerbors <bors@rust-lang.org>2021-05-12 08:01:10 +0000
commitaa15a5442a975180a367373e563b7f8c626b5344 (patch)
tree57359f3a59e7ef7dc6a3f616a092022d784e607e
parent0d4e24e73b28b33504df8daf1717e495f84fac40 (diff)
parenta988a90e112a68dd48222105f57556f97ea35fbd (diff)
downloadrust-aa15a5442a975180a367373e563b7f8c626b5344.tar.gz
rust-aa15a5442a975180a367373e563b7f8c626b5344.zip
Auto merge of #7197 - xFrednet:4310-depreciated-lints-collection, r=flip1995
Metadata collection monster eating deprecated lints

This adds the collection of deprecated lints to the metadata collection monster. The JSON output has the same structure with the *new* lint group "DEPRECATED". Here is one of fourteen examples it was able to dig up in Clippy's code:

```JSON
  {
    "id": "assign_op_pattern",
    "id_span": {
      "path": "src/assign_ops.rs",
      "line": 34
    },
    "group": "clippy::style",
    "docs": " **What it does:** Checks for `a = a op b` or `a = b commutative_op a` patterns.\n\n **Why is this bad?** These can be written as the shorter `a op= b`.\n\n **Known problems:** While forbidden by the spec, `OpAssign` traits may have\n implementations that differ from the regular `Op` impl.\n\n **Example:**\n ```rust\n let mut a = 5;\n let b = 0;\n // ...\n // Bad\n a = a + b;\n\n // Good\n a += b;\n ```\n",
    "applicability": {
      "is_multi_part_suggestion": false,
      "applicability": "MachineApplicable"
    }
  }
```

And you! Yes you! Sir or Madam can get all of this **for free** in Clippy if this PR gets merged. (Sorry for the silliness ^^)

---

See: #7172 for the full metadata collection to-do list or to suggest a new feature in connection to it :upside_down_face:

---

changelog: none

r? `@flip1995`
-rw-r--r--clippy_lints/src/deprecated_lints.rs11
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--clippy_lints/src/utils/internal_lints/metadata_collector.rs73
3 files changed, 62 insertions, 24 deletions
diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs
index 4688b3d5105..50ffc2e3f19 100644
--- a/clippy_lints/src/deprecated_lints.rs
+++ b/clippy_lints/src/deprecated_lints.rs
@@ -1,6 +1,13 @@
+/// This struct fakes the `Lint` declaration that is usually created by `declare_lint!`. This
+/// enables the simple extraction of the metadata without changing the current deprecation
+/// declaration.
+pub struct ClippyDeprecatedLint;
+
 macro_rules! declare_deprecated_lint {
-    (pub $name: ident, $_reason: expr) => {
-        declare_lint!(pub $name, Allow, "deprecated lint")
+    { $(#[$attr:meta])* pub $name: ident, $_reason: expr} => {
+        $(#[$attr])*
+        #[allow(dead_code)]
+        pub static $name: ClippyDeprecatedLint = ClippyDeprecatedLint {};
     }
 }
 
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 783bef73214..0c86441cf3f 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -162,6 +162,8 @@ macro_rules! extract_msrv_attr {
 mod consts;
 #[macro_use]
 mod utils;
+#[cfg(feature = "metadata-collector-lint")]
+mod deprecated_lints;
 
 // begin lints modules, do not remove this comment, it’s used in `update_lints`
 mod absurd_extreme_comparisons;
diff --git a/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index e85637ca758..fc4912ba52f 100644
--- a/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -8,9 +8,6 @@
 //! during any comparison or mapping. (Please take care of this, it's not fun to spend time on such
 //! a simple mistake)
 
-// # NITs
-// - TODO xFrednet 2021-02-13: Collect depreciations and maybe renames
-
 use if_chain::if_chain;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{
@@ -28,7 +25,7 @@ use std::path::Path;
 
 use crate::utils::internal_lints::is_lint_ref_type;
 use clippy_utils::{
-    diagnostics::span_lint, last_path_segment, match_function_call, match_path, paths, ty::match_type,
+    diagnostics::span_lint, last_path_segment, match_def_path, match_function_call, match_path, paths, ty::match_type,
     ty::walk_ptrs_ty_depth,
 };
 
@@ -41,6 +38,8 @@ const BLACK_LISTED_LINTS: [&str; 3] = ["lint_author", "deep_code_inspection", "i
 const IGNORED_LINT_GROUPS: [&str; 1] = ["clippy::all"];
 /// Lints within this group will be excluded from the collection
 const EXCLUDED_LINT_GROUPS: [&str; 1] = ["clippy::internal"];
+/// Collected deprecated lint will be assigned to this group in the JSON output
+const DEPRECATED_LINT_GROUP_STR: &str = "DEPRECATED";
 
 const LINT_EMISSION_FUNCTIONS: [&[&str]; 7] = [
     &["clippy_utils", "diagnostics", "span_lint"],
@@ -66,6 +65,7 @@ const SUGGESTION_FUNCTIONS: [&[&str]; 2] = [
     &["clippy_utils", "diagnostics", "multispan_sugg"],
     &["clippy_utils", "diagnostics", "multispan_sugg_with_applicability"],
 ];
+const DEPRECATED_LINT_TYPE: [&str; 3] = ["clippy_lints", "deprecated_lints", "ClippyDeprecatedLint"];
 
 /// The index of the applicability name of `paths::APPLICABILITY_VALUES`
 const APPLICABILITY_NAME_INDEX: usize = 2;
@@ -225,23 +225,42 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
     /// }
     /// ```
     fn check_item(&mut self, cx: &LateContext<'hir>, item: &'hir Item<'_>) {
-        if_chain! {
-            // item validation
-            if let ItemKind::Static(ref ty, Mutability::Not, _) = item.kind;
-            if is_lint_ref_type(cx, ty);
-            // blacklist check
-            let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
-            if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
-            // metadata extraction
-            if let Some(group) = get_lint_group_or_lint(cx, &lint_name, item);
-            if let Some(docs) = extract_attr_docs_or_lint(cx, item);
-            then {
-                self.lints.push(LintMetadata::new(
-                    lint_name,
-                    SerializableSpan::from_item(cx, item),
-                    group,
-                    docs,
-                ));
+        if let ItemKind::Static(ref ty, Mutability::Not, _) = item.kind {
+            // Normal lint
+            if_chain! {
+                // item validation
+                if is_lint_ref_type(cx, ty);
+                // blacklist check
+                let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
+                if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
+                // metadata extraction
+                if let Some(group) = get_lint_group_or_lint(cx, &lint_name, item);
+                if let Some(docs) = extract_attr_docs_or_lint(cx, item);
+                then {
+                    self.lints.push(LintMetadata::new(
+                        lint_name,
+                        SerializableSpan::from_item(cx, item),
+                        group,
+                        docs,
+                    ));
+                }
+            }
+
+            if_chain! {
+                if is_deprecated_lint(cx, ty);
+                // blacklist check
+                let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
+                if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
+                // Metadata the little we can get from a deprecated lint
+                if let Some(docs) = extract_attr_docs_or_lint(cx, item);
+                then {
+                    self.lints.push(LintMetadata::new(
+                        lint_name,
+                        SerializableSpan::from_item(cx, item),
+                        DEPRECATED_LINT_GROUP_STR.to_string(),
+                        docs,
+                    ));
+                }
             }
         }
     }
@@ -268,7 +287,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
                 // - src/misc.rs:734:9
                 // - src/methods/mod.rs:3545:13
                 // - src/methods/mod.rs:3496:13
-                // We are basically unable to resolve the lint name it self.
+                // We are basically unable to resolve the lint name itself.
                 return;
             }
 
@@ -347,6 +366,16 @@ fn get_lint_group(cx: &LateContext<'_>, lint_id: LintId) -> Option<String> {
     None
 }
 
+fn is_deprecated_lint(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
+    if let hir::TyKind::Path(ref path) = ty.kind {
+        if let hir::def::Res::Def(DefKind::Struct, def_id) = cx.qpath_res(path, ty.hir_id) {
+            return match_def_path(cx, def_id, &DEPRECATED_LINT_TYPE);
+        }
+    }
+
+    false
+}
+
 // ==================================================================
 // Lint emission
 // ==================================================================