Skip to content

Commit 0fddc6d

Browse files
committed
Metadata collection monster eating depreciated lints
1 parent 65951c9 commit 0fddc6d

File tree

3 files changed

+62
-21
lines changed

3 files changed

+62
-21
lines changed

clippy_lints/src/deprecated_lints.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1+
/// This struct fakes the `Lint` declaration that is usually created by `declare_lint!`. This
2+
/// enables the simple extraction of the metadata without changing the current depreciation
3+
/// declaration.
4+
pub struct ClippyDepreciatedLint;
5+
16
macro_rules! declare_deprecated_lint {
2-
(pub $name: ident, $_reason: expr) => {
3-
declare_lint!(pub $name, Allow, "deprecated lint")
7+
{ $(#[$attr:meta])* pub $name: ident, $_reason: expr} => {
8+
$(#[$attr])*
9+
#[allow(dead_code)]
10+
pub static $name: ClippyDepreciatedLint = ClippyDepreciatedLint {};
411
}
512
}
613

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ macro_rules! extract_msrv_attr {
162162
mod consts;
163163
#[macro_use]
164164
mod utils;
165+
#[cfg(feature = "metadata-collector-lint")]
166+
mod deprecated_lints;
165167

166168
// begin lints modules, do not remove this comment, it’s used in `update_lints`
167169
mod absurd_extreme_comparisons;

clippy_lints/src/utils/internal_lints/metadata_collector.rs

+51-19
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use std::path::Path;
2828

2929
use crate::utils::internal_lints::is_lint_ref_type;
3030
use clippy_utils::{
31-
diagnostics::span_lint, last_path_segment, match_function_call, match_path, paths, ty::match_type,
31+
diagnostics::span_lint, last_path_segment, match_def_path, match_function_call, match_path, paths, ty::match_type,
3232
ty::walk_ptrs_ty_depth,
3333
};
3434

@@ -41,6 +41,8 @@ const BLACK_LISTED_LINTS: [&str; 3] = ["lint_author", "deep_code_inspection", "i
4141
const IGNORED_LINT_GROUPS: [&str; 1] = ["clippy::all"];
4242
/// Lints within this group will be excluded from the collection
4343
const EXCLUDED_LINT_GROUPS: [&str; 1] = ["clippy::internal"];
44+
/// Collected depreciated lint will be assigned to this group in the JSON output
45+
const DEPRECIATED_LINT_GROUP_STR: &str = "DEPRECIATED";
4446

4547
const LINT_EMISSION_FUNCTIONS: [&[&str]; 7] = [
4648
&["clippy_utils", "diagnostics", "span_lint"],
@@ -66,6 +68,7 @@ const SUGGESTION_FUNCTIONS: [&[&str]; 2] = [
6668
&["clippy_utils", "diagnostics", "multispan_sugg"],
6769
&["clippy_utils", "diagnostics", "multispan_sugg_with_applicability"],
6870
];
71+
const DEPRECIATED_LINT_TYPE: [&str; 3] = ["clippy_lints", "deprecated_lints", "ClippyDepreciatedLint"];
6972

7073
/// The index of the applicability name of `paths::APPLICABILITY_VALUES`
7174
const APPLICABILITY_NAME_INDEX: usize = 2;
@@ -225,23 +228,42 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
225228
/// }
226229
/// ```
227230
fn check_item(&mut self, cx: &LateContext<'hir>, item: &'hir Item<'_>) {
228-
if_chain! {
229-
// item validation
230-
if let ItemKind::Static(ref ty, Mutability::Not, _) = item.kind;
231-
if is_lint_ref_type(cx, ty);
232-
// blacklist check
233-
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
234-
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
235-
// metadata extraction
236-
if let Some(group) = get_lint_group_or_lint(cx, &lint_name, item);
237-
if let Some(docs) = extract_attr_docs_or_lint(cx, item);
238-
then {
239-
self.lints.push(LintMetadata::new(
240-
lint_name,
241-
SerializableSpan::from_item(cx, item),
242-
group,
243-
docs,
244-
));
231+
if let ItemKind::Static(ref ty, Mutability::Not, _) = item.kind {
232+
// Normal lint
233+
if_chain! {
234+
// item validation
235+
if is_lint_ref_type(cx, ty);
236+
// blacklist check
237+
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
238+
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
239+
// metadata extraction
240+
if let Some(group) = get_lint_group_or_lint(cx, &lint_name, item);
241+
if let Some(docs) = extract_attr_docs_or_lint(cx, item);
242+
then {
243+
self.lints.push(LintMetadata::new(
244+
lint_name,
245+
SerializableSpan::from_item(cx, item),
246+
group,
247+
docs,
248+
));
249+
}
250+
}
251+
252+
if_chain! {
253+
if is_depreciated_lint(cx, ty);
254+
// blacklist check
255+
let lint_name = sym_to_string(item.ident.name).to_ascii_lowercase();
256+
if !BLACK_LISTED_LINTS.contains(&lint_name.as_str());
257+
// Metadata the little we can get from a depreciated lint
258+
if let Some(docs) = extract_attr_docs_or_lint(cx, item);
259+
then {
260+
self.lints.push(LintMetadata::new(
261+
lint_name,
262+
SerializableSpan::from_item(cx, item),
263+
DEPRECIATED_LINT_GROUP_STR.to_string(),
264+
docs,
265+
));
266+
}
245267
}
246268
}
247269
}
@@ -268,7 +290,7 @@ impl<'hir> LateLintPass<'hir> for MetadataCollector {
268290
// - src/misc.rs:734:9
269291
// - src/methods/mod.rs:3545:13
270292
// - src/methods/mod.rs:3496:13
271-
// We are basically unable to resolve the lint name it self.
293+
// We are basically unable to resolve the lint name itself.
272294
return;
273295
}
274296

@@ -347,6 +369,16 @@ fn get_lint_group(cx: &LateContext<'_>, lint_id: LintId) -> Option<String> {
347369
None
348370
}
349371

372+
fn is_depreciated_lint(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
373+
if let hir::TyKind::Path(ref path) = ty.kind {
374+
if let hir::def::Res::Def(DefKind::Struct, def_id) = cx.qpath_res(path, ty.hir_id) {
375+
return match_def_path(cx, def_id, &DEPRECIATED_LINT_TYPE);
376+
}
377+
}
378+
379+
false
380+
}
381+
350382
// ==================================================================
351383
// Lint emission
352384
// ==================================================================

0 commit comments

Comments
 (0)