Skip to content

Commit 36248af

Browse files
committed
Migrate Some metadata collection to the general branch + add config to --explain
1 parent f9c1d15 commit 36248af

File tree

9 files changed

+112
-65
lines changed

9 files changed

+112
-65
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ rustc-semver = "1.1"
5858
rustc_tools_util = "0.3.0"
5959

6060
[features]
61-
deny-warnings = ["clippy_lints/deny-warnings"]
61+
deny-warnings = ["clippy_lints/deny-warnings", "internal"]
6262
integration = ["tempfile"]
6363
internal = ["clippy_lints/internal", "tempfile"]
6464

clippy_lints/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pulldown-cmark = { version = "0.9", default-features = false }
1919
quine-mc_cluskey = "0.2"
2020
regex-syntax = "0.6"
2121
serde = { version = "1.0", features = ["derive"] }
22-
serde_json = { version = "1.0", optional = true }
23-
tempfile = { version = "3.3.0", optional = true }
22+
serde_json = "1.0"
23+
tempfile = "3.3.0"
2424
toml = "0.5"
2525
unicode-normalization = "0.1"
2626
unicode-script = { version = "0.5", default-features = false }
@@ -33,7 +33,7 @@ url = { version = "2.2", features = ["serde"] }
3333
[features]
3434
deny-warnings = ["clippy_utils/deny-warnings"]
3535
# build clippy with internal lints enabled, off by default
36-
internal = ["clippy_utils/internal", "serde_json", "tempfile"]
36+
internal = ["clippy_utils/internal"]
3737

3838
[package.metadata.rust-analyzer]
3939
# This crate uses #[feature(rustc_private)]

clippy_lints/src/lib.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,11 @@ mod zero_div_zero;
331331
mod zero_sized_map_values;
332332
// end lints modules, do not remove this comment, it’s used in `update_lints`
333333

334-
use crate::utils::conf::{format_error, TryConf};
335334
pub use crate::utils::conf::{lookup_conf_file, Conf};
335+
use crate::utils::{
336+
conf::{format_error, metadata::get_configuration_metadata, TryConf},
337+
FindAll,
338+
};
336339

337340
/// Register all pre expansion lints
338341
///
@@ -388,7 +391,7 @@ pub fn read_conf(sess: &Session, path: &io::Result<(Option<PathBuf>, Vec<String>
388391
conf
389392
}
390393

391-
#[derive(Default)]
394+
#[derive(Default)] //~ ERROR no such field
392395
struct RegistrationGroups {
393396
all: Vec<LintId>,
394397
cargo: Vec<LintId>,
@@ -471,7 +474,23 @@ pub(crate) struct LintInfo {
471474
pub fn explain(name: &str) {
472475
let target = format!("clippy::{}", name.to_ascii_uppercase());
473476
match declared_lints::LINTS.iter().find(|info| info.lint.name == target) {
474-
Some(info) => print!("{}", info.explanation),
477+
Some(info) => {
478+
println!("{}", info.explanation);
479+
// Check if the lint has configuration
480+
let mdconf = get_configuration_metadata();
481+
if let Some(config_vec_positions) = mdconf
482+
.iter()
483+
.find_all(|cconf| cconf.lints.contains(&info.lint.name_lower()[8..].to_owned()))
484+
{
485+
// If it has, print it
486+
println!("========================================");
487+
println!("Configuration for {}:", info.lint.name_lower());
488+
for position in config_vec_positions {
489+
let conf = &mdconf[position];
490+
println!("- {}: {} (default: {})", conf.name, conf.doc, conf.default);
491+
}
492+
}
493+
},
475494
None => println!("unknown lint: {name}"),
476495
}
477496
}
@@ -506,7 +525,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
506525
#[cfg(feature = "internal")]
507526
{
508527
if std::env::var("ENABLE_METADATA_COLLECTION").eq(&Ok("1".to_string())) {
509-
store.register_late_pass(|_| Box::new(utils::internal_lints::metadata_collector::MetadataCollector::new()));
528+
store.register_late_pass(|_| Box::new(utils::metadata_collector::MetadataCollector::new()));
510529
return;
511530
}
512531
}

clippy_lints/src/utils/conf.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,16 +174,15 @@ macro_rules! define_Conf {
174174
}
175175
}
176176

177-
#[cfg(feature = "internal")]
178177
pub mod metadata {
179-
use crate::utils::internal_lints::metadata_collector::ClippyConfiguration;
178+
use crate::utils::metadata_collector::ClippyConfiguration;
180179

181180
macro_rules! wrap_option {
182181
() => (None);
183182
($x:literal) => (Some($x));
184183
}
185184

186-
pub(crate) fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
185+
pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
187186
vec![
188187
$(
189188
{

clippy_lints/src/utils/internal_lints.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ pub mod if_chain_style;
55
pub mod interning_defined_symbol;
66
pub mod invalid_paths;
77
pub mod lint_without_lint_pass;
8-
pub mod metadata_collector;
98
pub mod msrv_attr_impl;
109
pub mod outer_expn_data_pass;
1110
pub mod produce_ice;

clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs

Lines changed: 5 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
use crate::utils::internal_lints::metadata_collector::is_deprecated_lint;
1+
use crate::utils::metadata_collector::is_deprecated_lint;
2+
use crate::utils::{extract_clippy_version_value, is_lint_ref_type};
23
use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
4+
use clippy_utils::is_lint_allowed;
35
use clippy_utils::macros::root_macro_call_first_node;
4-
use clippy_utils::{is_lint_allowed, match_def_path, paths};
5-
use if_chain::if_chain;
6-
use rustc_ast as ast;
76
use rustc_ast::ast::LitKind;
87
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
98
use rustc_hir as hir;
10-
use rustc_hir::def::{DefKind, Res};
119
use rustc_hir::hir_id::CRATE_HIR_ID;
1210
use rustc_hir::intravisit::Visitor;
13-
use rustc_hir::{ExprKind, HirId, Item, MutTy, Mutability, Path, TyKind};
11+
use rustc_hir::{ExprKind, HirId, Item, Mutability, Path};
1412
use rustc_lint::{LateContext, LateLintPass};
1513
use rustc_middle::hir::nested_filter;
1614
use rustc_semver::RustcVersion;
1715
use rustc_session::{declare_tool_lint, impl_lint_pass};
1816
use rustc_span::source_map::Spanned;
1917
use rustc_span::symbol::Symbol;
20-
use rustc_span::{sym, Span};
18+
use rustc_span::Span;
2119

2220
declare_clippy_lint! {
2321
/// ### What it does
@@ -255,25 +253,6 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
255253
}
256254
}
257255

258-
pub(super) fn is_lint_ref_type(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
259-
if let TyKind::Ref(
260-
_,
261-
MutTy {
262-
ty: inner,
263-
mutbl: Mutability::Not,
264-
},
265-
) = ty.kind
266-
{
267-
if let TyKind::Path(ref path) = inner.kind {
268-
if let Res::Def(DefKind::Struct, def_id) = cx.qpath_res(path, inner.hir_id) {
269-
return match_def_path(cx, def_id, &paths::LINT);
270-
}
271-
}
272-
}
273-
274-
false
275-
}
276-
277256
fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'_>) {
278257
if let Some(value) = extract_clippy_version_value(cx, item) {
279258
// The `sym!` macro doesn't work as it only expects a single token.
@@ -304,23 +283,6 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'
304283
}
305284
}
306285

307-
/// This function extracts the version value of a `clippy::version` attribute if the given value has
308-
/// one
309-
pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option<Symbol> {
310-
let attrs = cx.tcx.hir().attrs(item.hir_id());
311-
attrs.iter().find_map(|attr| {
312-
if_chain! {
313-
// Identify attribute
314-
if let ast::AttrKind::Normal(ref attr_kind) = &attr.kind;
315-
if let [tool_name, attr_name] = &attr_kind.item.path.segments[..];
316-
if tool_name.ident.name == sym::clippy;
317-
if attr_name.ident.name == sym::version;
318-
if let Some(version) = attr.value_str();
319-
then { Some(version) } else { None }
320-
}
321-
})
322-
}
323-
324286
struct LintCollector<'a, 'tcx> {
325287
output: &'a mut FxHashSet<Symbol>,
326288
cx: &'a LateContext<'tcx>,

clippy_lints/src/utils/internal_lints/metadata_collector.rs renamed to clippy_lints/src/utils/metadata_collector.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
//! a simple mistake)
99
1010
use crate::renamed_lints::RENAMED_LINTS;
11-
use crate::utils::internal_lints::lint_without_lint_pass::{extract_clippy_version_value, is_lint_ref_type};
11+
use crate::utils::{extract_clippy_version_value, is_lint_ref_type};
1212

1313
use clippy_utils::diagnostics::span_lint;
1414
use clippy_utils::ty::{match_type, walk_ptrs_ty_depth};
@@ -143,7 +143,7 @@ pub struct MetadataCollector {
143143
/// We use a Heap here to have the lints added in alphabetic order in the export
144144
lints: BinaryHeap<LintMetadata>,
145145
applicability_info: FxHashMap<String, ApplicabilityInfo>,
146-
config: Vec<ClippyConfiguration>,
146+
pub(crate) config: Vec<ClippyConfiguration>,
147147
clippy_project_root: PathBuf,
148148
}
149149

@@ -525,11 +525,11 @@ impl Serialize for ApplicabilityInfo {
525525
// ==================================================================
526526
#[derive(Debug, Clone, Default)]
527527
pub struct ClippyConfiguration {
528-
name: String,
528+
pub name: String,
529529
config_type: &'static str,
530-
default: String,
531-
lints: Vec<String>,
532-
doc: String,
530+
pub default: String,
531+
pub lints: Vec<String>,
532+
pub doc: String,
533533
#[allow(dead_code)]
534534
deprecation_reason: Option<&'static str>,
535535
}

clippy_lints/src/utils/mod.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,78 @@
1+
use clippy_utils::{match_def_path, paths};
2+
use rustc_ast::ast;
3+
use rustc_hir::{def::DefKind, def::Res, Item, MutTy, Mutability, Ty, TyKind};
4+
use rustc_lint::LateContext;
5+
use rustc_span::{sym, Symbol};
6+
17
pub mod author;
28
pub mod conf;
39
pub mod dump_hir;
410
pub mod format_args_collector;
511
#[cfg(feature = "internal")]
612
pub mod internal_lints;
13+
pub mod metadata_collector;
14+
15+
/// This function extracts the version value of a `clippy::version` attribute if the given value has
16+
/// one
17+
pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option<Symbol> {
18+
let attrs = cx.tcx.hir().attrs(item.hir_id());
19+
attrs.iter().find_map(|attr| {
20+
if_chain! {
21+
// Identify attribute
22+
if let ast::AttrKind::Normal(ref attr_kind) = &attr.kind;
23+
if let [tool_name, attr_name] = &attr_kind.item.path.segments[..];
24+
if tool_name.ident.name == sym::clippy;
25+
if attr_name.ident.name == sym::version;
26+
if let Some(version) = attr.value_str();
27+
then { Some(version) } else { None }
28+
}
29+
})
30+
}
31+
32+
pub(super) fn is_lint_ref_type(cx: &LateContext<'_>, ty: &Ty<'_>) -> bool {
33+
if let TyKind::Ref(
34+
_,
35+
MutTy {
36+
ty: inner,
37+
mutbl: Mutability::Not,
38+
},
39+
) = ty.kind
40+
{
41+
if let TyKind::Path(ref path) = inner.kind {
42+
if let Res::Def(DefKind::Struct, def_id) = cx.qpath_res(path, inner.hir_id) {
43+
return match_def_path(cx, def_id, &paths::LINT);
44+
}
45+
}
46+
}
47+
48+
false
49+
}
50+
51+
// Shamelessly stolen from find_all (https://github.com/nectariner/find_all)
52+
pub trait FindAll: Iterator + Sized {
53+
fn find_all<P>(&mut self, predicate: P) -> Option<Vec<usize>>
54+
where
55+
P: FnMut(&Self::Item) -> bool;
56+
}
57+
58+
impl<I> FindAll for I
59+
where
60+
I: Iterator,
61+
{
62+
fn find_all<P>(&mut self, mut predicate: P) -> Option<Vec<usize>>
63+
where
64+
P: FnMut(&Self::Item) -> bool,
65+
{
66+
let mut occurences = Vec::<usize>::default();
67+
for (index, element) in self.enumerate() {
68+
if predicate(&element) {
69+
occurences.push(index);
70+
}
71+
}
72+
73+
match occurences.len() {
74+
0 => None,
75+
_ => Some(occurences),
76+
}
77+
}
78+
}

clippy_utils/src/paths.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,13 @@
44
//! Whenever possible, please consider diagnostic items over hardcoded paths.
55
//! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.
66
7-
#[cfg(feature = "internal")]
87
pub const APPLICABILITY: [&str; 2] = ["rustc_lint_defs", "Applicability"];
9-
#[cfg(feature = "internal")]
108
pub const APPLICABILITY_VALUES: [[&str; 3]; 4] = [
119
["rustc_lint_defs", "Applicability", "Unspecified"],
1210
["rustc_lint_defs", "Applicability", "HasPlaceholders"],
1311
["rustc_lint_defs", "Applicability", "MaybeIncorrect"],
1412
["rustc_lint_defs", "Applicability", "MachineApplicable"],
1513
];
16-
#[cfg(feature = "internal")]
1714
pub const DIAGNOSTIC_BUILDER: [&str; 3] = ["rustc_errors", "diagnostic_builder", "DiagnosticBuilder"];
1815
pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
1916
pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"];
@@ -56,7 +53,6 @@ pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
5653
pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
5754
#[cfg(feature = "internal")]
5855
pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
59-
#[cfg(feature = "internal")]
6056
pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
6157
pub const MEM_SWAP: [&str; 3] = ["core", "mem", "swap"];
6258
#[cfg(feature = "internal")]

0 commit comments

Comments
 (0)