Skip to content

Commit

Permalink
Auto merge of rust-lang#7197 - xFrednet:4310-depreciated-lints-collec…
Browse files Browse the repository at this point in the history
…tion, 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: rust-lang#7172 for the full metadata collection to-do list or to suggest a new feature in connection to it 🙃

---

changelog: none

r? `@flip1995`
  • Loading branch information
bors committed May 12, 2021
2 parents 0d4e24e + a988a90 commit aa15a54
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 24 deletions.
11 changes: 9 additions & 2 deletions clippy_lints/src/deprecated_lints.rs
Original file line number Diff line number Diff line change
@@ -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 {};
}
}

Expand Down
2 changes: 2 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
73 changes: 51 additions & 22 deletions clippy_lints/src/utils/internal_lints/metadata_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand All @@ -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,
};

Expand All @@ -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"],
Expand All @@ -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;
Expand Down Expand Up @@ -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,
));
}
}
}
}
Expand All @@ -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;
}

Expand Down Expand Up @@ -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
// ==================================================================
Expand Down

0 comments on commit aa15a54

Please sign in to comment.