Skip to content

Commit b3e0e17

Browse files
authored
Fix --explain lint lookup being case-mismatched (#17632)
`cargo clippy --explain <lint>` prints `unknown lint` for every lint on beta and nightly. `src/main.rs` lowercases the argument, but `Lint::name` is uppercase (`clippy::ALLOW_ATTRIBUTES`), so the lookup in `explain` never matches. The `to_ascii_uppercase` that reconciled the two was dropped in c97f7eb ("Rewrite of the config parsing code"), and this restores that line verbatim. `beta` and `master` carry the commit, stable 0.1.98 does not, which is why `--explain` still works there. The lowercase rebinding below the lookup is deliberately left alone. `mdconf.retain(...)` keys on that form, so removing it would silently drop every configuration section. The tests are new because `--explain` had no coverage at all, which is how this went unreported for three weeks. `cargo test --features internal` passes here apart from the 16 `tests/ui-internal` cases, which fail the same way on an unmodified master checkout, so they look local to my Windows setup. #17573 moves this code and inherits the same mismatch, so whichever lands second needs a small rebase. fixes #17620 changelog: Fix `cargo clippy --explain <lint>` reporting `unknown lint` for every lint
2 parents 6b45a69 + 52bb2d9 commit b3e0e17

2 files changed

Lines changed: 45 additions & 1 deletion

File tree

clippy_lints/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ use rustc_middle::ty::TyCtxt;
423423
use utils::attr_collector::AttrStorage;
424424

425425
pub fn explain(name: &str) -> i32 {
426-
let target = format!("clippy::{name}");
426+
let target = format!("clippy::{}", name.to_ascii_uppercase());
427427
if let Some(info) = declared_lints::LINTS.iter().find(|info| info.lint.name == target) {
428428
println!("{}", sanitize_explanation(info.explanation));
429429
// Check if the lint has configuration

tests/explain.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//! Checks `--explain` against the forms of a lint name a user may actually type.
2+
//!
3+
//! `src/main.rs` lowercases the argument, strips a `clippy::` prefix and replaces
4+
//! `-` with `_` before `clippy_lints::explain` looks the name up in its uppercase
5+
//! form. Calling `explain` directly would leave that conversion untested.
6+
//!
7+
//! This test is a no-op if run as part of the compiler test suite
8+
//! and will always succeed.
9+
10+
use std::process::{Command, Stdio};
11+
use test_utils::{CARGO_CLIPPY_PATH, IS_RUSTC_TEST_SUITE};
12+
13+
mod test_utils;
14+
15+
#[test]
16+
fn explain() {
17+
if IS_RUSTC_TEST_SUITE {
18+
return;
19+
}
20+
21+
let running = [
22+
("allow-attributes", true),
23+
("clippy::allow_attributes", true),
24+
("TOPLEVEL_REF_ARG", true),
25+
("CLIPPY::TOPLEVEL_REF_ARG", true),
26+
("not_a_lint", false),
27+
]
28+
.map(|(arg, found)| {
29+
let child = Command::new(&*CARGO_CLIPPY_PATH)
30+
.args(["--explain", arg])
31+
.stdout(Stdio::null())
32+
.spawn()
33+
.unwrap();
34+
(arg, found, child)
35+
});
36+
37+
for (arg, found, mut child) in running {
38+
assert_eq!(
39+
child.wait().unwrap().success(),
40+
found,
41+
"unexpected result for `--explain {arg}`"
42+
);
43+
}
44+
}

0 commit comments

Comments
 (0)