Skip to content

Commit a8d2584

Browse files
bors[bot]flip1995
andcommitted
Merge #3161
3161: New lint: Unknown clippy lints r=phansch a=flip1995 This is the Clippy version of the `rustc` lint `unknown_lints`. The behavior of this lint is pretty much the same. Before this is merged a small change in the compiler needs to be done: `CheckLintNameResult` needs to be public. See #54106 Co-authored-by: flip1995 <[email protected]> Co-authored-by: flip1995 <[email protected]>
2 parents 6256892 + 32396f6 commit a8d2584

File tree

6 files changed

+122
-8
lines changed

6 files changed

+122
-8
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@ All notable changes to this project will be documented in this file.
866866
[`unimplemented`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unimplemented
867867
[`unit_arg`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unit_arg
868868
[`unit_cmp`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unit_cmp
869+
[`unknown_clippy_lints`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unknown_clippy_lints
869870
[`unnecessary_cast`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_cast
870871
[`unnecessary_filter_map`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_filter_map
871872
[`unnecessary_fold`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_fold

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ We are currently in the process of discussing Clippy 1.0 via the RFC process in
99

1010
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
1111

12-
[There are 283 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
12+
[There are 284 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
1313

1414
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
1515

clippy_lints/src/attrs.rs

+86-7
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,20 @@
1212
1313
use crate::reexport::*;
1414
use crate::utils::{
15-
in_macro, last_line_of_span, match_def_path, opt_def_id, paths, snippet_opt, span_lint, span_lint_and_then,
16-
without_block_comments,
15+
in_macro, last_line_of_span, match_def_path, opt_def_id, paths, snippet_opt, span_lint,
16+
span_lint_and_then, without_block_comments,
1717
};
18-
use crate::rustc::hir::*;
19-
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
20-
use crate::rustc::{declare_tool_lint, lint_array};
2118
use if_chain::if_chain;
19+
use crate::rustc::hir::*;
20+
use crate::rustc::lint::{
21+
CheckLintNameResult, LateContext, LateLintPass, LintArray, LintContext, LintPass,
22+
};
2223
use crate::rustc::ty::{self, TyCtxt};
24+
use crate::rustc::{declare_tool_lint, lint_array};
2325
use semver::Version;
24-
use crate::syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
26+
use crate::syntax::ast::{
27+
AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind,
28+
};
2529
use crate::syntax::source_map::Span;
2630
use crate::rustc_errors::Applicability;
2731

@@ -138,6 +142,33 @@ declare_clippy_lint! {
138142
"empty line after outer attribute"
139143
}
140144

145+
/// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy
146+
/// lints and if those lints exist in clippy. If there is a uppercase letter in the lint name
147+
/// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase
148+
/// the lint name.
149+
///
150+
/// **Why is this bad?** A lint attribute with a mistyped lint name won't have an effect.
151+
///
152+
/// **Known problems:** None.
153+
///
154+
/// **Example:**
155+
/// Bad:
156+
/// ```rust
157+
/// #![warn(if_not_els)]
158+
/// #![deny(clippy::All)]
159+
/// ```
160+
///
161+
/// Good:
162+
/// ```rust
163+
/// #![warn(if_not_else)]
164+
/// #![deny(clippy::all)]
165+
/// ```
166+
declare_clippy_lint! {
167+
pub UNKNOWN_CLIPPY_LINTS,
168+
style,
169+
"unknown_lints for scoped Clippy lints"
170+
}
171+
141172
#[derive(Copy, Clone)]
142173
pub struct AttrPass;
143174

@@ -147,14 +178,21 @@ impl LintPass for AttrPass {
147178
INLINE_ALWAYS,
148179
DEPRECATED_SEMVER,
149180
USELESS_ATTRIBUTE,
150-
EMPTY_LINE_AFTER_OUTER_ATTR
181+
EMPTY_LINE_AFTER_OUTER_ATTR,
182+
UNKNOWN_CLIPPY_LINTS,
151183
)
152184
}
153185
}
154186

155187
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
156188
fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute) {
157189
if let Some(ref items) = attr.meta_item_list() {
190+
match &*attr.name().as_str() {
191+
"allow" | "warn" | "deny" | "forbid" => {
192+
check_clippy_lint_names(cx, items);
193+
}
194+
_ => {}
195+
}
158196
if items.is_empty() || attr.name() != "deprecated" {
159197
return;
160198
}
@@ -247,6 +285,47 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
247285
}
248286
}
249287

288+
#[allow(clippy::single_match_else)]
289+
fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) {
290+
let lint_store = cx.lints();
291+
for lint in items {
292+
if_chain! {
293+
if let Some(word) = lint.word();
294+
if let Some(tool_name) = word.is_scoped();
295+
if tool_name.as_str() == "clippy";
296+
let name = word.name();
297+
if let CheckLintNameResult::Tool(Err((None, _))) = lint_store.check_lint_name(
298+
&name.as_str(),
299+
Some(tool_name.as_str()),
300+
);
301+
then {
302+
span_lint_and_then(
303+
cx,
304+
UNKNOWN_CLIPPY_LINTS,
305+
lint.span,
306+
&format!("unknown clippy lint: clippy::{}", name),
307+
|db| {
308+
if name.as_str().chars().any(|c| c.is_uppercase()) {
309+
let name_lower = name.as_str().to_lowercase().to_string();
310+
match lint_store.check_lint_name(
311+
&name_lower,
312+
Some(tool_name.as_str())
313+
) {
314+
CheckLintNameResult::NoLint => (),
315+
_ => {
316+
db.span_suggestion(lint.span,
317+
"lowercase the lint name",
318+
name_lower);
319+
}
320+
}
321+
}
322+
}
323+
);
324+
}
325+
};
326+
}
327+
}
328+
250329
fn is_relevant_item(tcx: TyCtxt<'_, '_, '_>, item: &Item) -> bool {
251330
if let ItemKind::Fn(_, _, _, eid) = item.node {
252331
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)

clippy_lints/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
533533
assign_ops::ASSIGN_OP_PATTERN,
534534
assign_ops::MISREFACTORED_ASSIGN_OP,
535535
attrs::DEPRECATED_SEMVER,
536+
attrs::UNKNOWN_CLIPPY_LINTS,
536537
attrs::USELESS_ATTRIBUTE,
537538
bit_mask::BAD_BIT_MASK,
538539
bit_mask::INEFFECTIVE_BIT_MASK,
@@ -749,6 +750,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
749750

750751
reg.register_lint_group("clippy::style", Some("clippy_style"), vec![
751752
assign_ops::ASSIGN_OP_PATTERN,
753+
attrs::UNKNOWN_CLIPPY_LINTS,
752754
bit_mask::VERBOSE_BIT_MASK,
753755
blacklisted_name::BLACKLISTED_NAME,
754756
block_in_if_condition::BLOCK_IN_IF_CONDITION_EXPR,

tests/ui/unknown_clippy_lints.rs

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution.
3+
//
4+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7+
// option. This file may not be copied, modified, or distributed
8+
// except according to those terms.
9+
10+
#![allow(clippy::All)]
11+
#![warn(clippy::pedantic)]
12+
13+
#[warn(clippy::if_not_els)]
14+
fn main() {
15+
16+
}

tests/ui/unknown_clippy_lints.stderr

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: unknown clippy lint: clippy::if_not_els
2+
--> $DIR/unknown_clippy_lints.rs:13:8
3+
|
4+
13 | #[warn(clippy::if_not_els)]
5+
| ^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `-D clippy::unknown-clippy-lints` implied by `-D warnings`
8+
9+
error: unknown clippy lint: clippy::All
10+
--> $DIR/unknown_clippy_lints.rs:10:10
11+
|
12+
10 | #![allow(clippy::All)]
13+
| ^^^^^^^^^^^ help: lowercase the lint name: `all`
14+
15+
error: aborting due to 2 previous errors
16+

0 commit comments

Comments
 (0)