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 rust-lang/rust#54106 Co-authored-by: flip1995 <9744647+flip1995@users.noreply.github.com> Co-authored-by: flip1995 <hello@philkrones.com>
This commit is contained in:
commit
a8d258454f
@ -866,6 +866,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
[`unimplemented`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unimplemented
|
[`unimplemented`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unimplemented
|
||||||
[`unit_arg`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unit_arg
|
[`unit_arg`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unit_arg
|
||||||
[`unit_cmp`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unit_cmp
|
[`unit_cmp`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unit_cmp
|
||||||
|
[`unknown_clippy_lints`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unknown_clippy_lints
|
||||||
[`unnecessary_cast`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_cast
|
[`unnecessary_cast`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_cast
|
||||||
[`unnecessary_filter_map`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_filter_map
|
[`unnecessary_filter_map`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_filter_map
|
||||||
[`unnecessary_fold`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_fold
|
[`unnecessary_fold`]: https://rust-lang-nursery.github.io/rust-clippy/master/index.html#unnecessary_fold
|
||||||
|
@ -9,7 +9,7 @@ We are currently in the process of discussing Clippy 1.0 via the RFC process in
|
|||||||
|
|
||||||
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
||||||
|
|
||||||
[There are 283 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
|
[There are 284 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html)
|
||||||
|
|
||||||
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
|
||||||
|
|
||||||
|
@ -12,16 +12,20 @@
|
|||||||
|
|
||||||
use crate::reexport::*;
|
use crate::reexport::*;
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
in_macro, last_line_of_span, match_def_path, opt_def_id, paths, snippet_opt, span_lint, span_lint_and_then,
|
in_macro, last_line_of_span, match_def_path, opt_def_id, paths, snippet_opt, span_lint,
|
||||||
without_block_comments,
|
span_lint_and_then, without_block_comments,
|
||||||
};
|
};
|
||||||
use crate::rustc::hir::*;
|
|
||||||
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
|
|
||||||
use crate::rustc::{declare_tool_lint, lint_array};
|
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
|
use crate::rustc::hir::*;
|
||||||
|
use crate::rustc::lint::{
|
||||||
|
CheckLintNameResult, LateContext, LateLintPass, LintArray, LintContext, LintPass,
|
||||||
|
};
|
||||||
use crate::rustc::ty::{self, TyCtxt};
|
use crate::rustc::ty::{self, TyCtxt};
|
||||||
|
use crate::rustc::{declare_tool_lint, lint_array};
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
use crate::syntax::ast::{AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
|
use crate::syntax::ast::{
|
||||||
|
AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem, NestedMetaItemKind,
|
||||||
|
};
|
||||||
use crate::syntax::source_map::Span;
|
use crate::syntax::source_map::Span;
|
||||||
use crate::rustc_errors::Applicability;
|
use crate::rustc_errors::Applicability;
|
||||||
|
|
||||||
@ -138,6 +142,33 @@ declare_clippy_lint! {
|
|||||||
"empty line after outer attribute"
|
"empty line after outer attribute"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// **What it does:** Checks for `allow`/`warn`/`deny`/`forbid` attributes with scoped clippy
|
||||||
|
/// lints and if those lints exist in clippy. If there is a uppercase letter in the lint name
|
||||||
|
/// (not the tool name) and a lowercase version of this lint exists, it will suggest to lowercase
|
||||||
|
/// the lint name.
|
||||||
|
///
|
||||||
|
/// **Why is this bad?** A lint attribute with a mistyped lint name won't have an effect.
|
||||||
|
///
|
||||||
|
/// **Known problems:** None.
|
||||||
|
///
|
||||||
|
/// **Example:**
|
||||||
|
/// Bad:
|
||||||
|
/// ```rust
|
||||||
|
/// #![warn(if_not_els)]
|
||||||
|
/// #![deny(clippy::All)]
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Good:
|
||||||
|
/// ```rust
|
||||||
|
/// #![warn(if_not_else)]
|
||||||
|
/// #![deny(clippy::all)]
|
||||||
|
/// ```
|
||||||
|
declare_clippy_lint! {
|
||||||
|
pub UNKNOWN_CLIPPY_LINTS,
|
||||||
|
style,
|
||||||
|
"unknown_lints for scoped Clippy lints"
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct AttrPass;
|
pub struct AttrPass;
|
||||||
|
|
||||||
@ -147,7 +178,8 @@ impl LintPass for AttrPass {
|
|||||||
INLINE_ALWAYS,
|
INLINE_ALWAYS,
|
||||||
DEPRECATED_SEMVER,
|
DEPRECATED_SEMVER,
|
||||||
USELESS_ATTRIBUTE,
|
USELESS_ATTRIBUTE,
|
||||||
EMPTY_LINE_AFTER_OUTER_ATTR
|
EMPTY_LINE_AFTER_OUTER_ATTR,
|
||||||
|
UNKNOWN_CLIPPY_LINTS,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -155,6 +187,12 @@ impl LintPass for AttrPass {
|
|||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
|
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
|
||||||
fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute) {
|
fn check_attribute(&mut self, cx: &LateContext<'a, 'tcx>, attr: &'tcx Attribute) {
|
||||||
if let Some(ref items) = attr.meta_item_list() {
|
if let Some(ref items) = attr.meta_item_list() {
|
||||||
|
match &*attr.name().as_str() {
|
||||||
|
"allow" | "warn" | "deny" | "forbid" => {
|
||||||
|
check_clippy_lint_names(cx, items);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
if items.is_empty() || attr.name() != "deprecated" {
|
if items.is_empty() || attr.name() != "deprecated" {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -247,6 +285,47 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AttrPass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::single_match_else)]
|
||||||
|
fn check_clippy_lint_names(cx: &LateContext<'_, '_>, items: &[NestedMetaItem]) {
|
||||||
|
let lint_store = cx.lints();
|
||||||
|
for lint in items {
|
||||||
|
if_chain! {
|
||||||
|
if let Some(word) = lint.word();
|
||||||
|
if let Some(tool_name) = word.is_scoped();
|
||||||
|
if tool_name.as_str() == "clippy";
|
||||||
|
let name = word.name();
|
||||||
|
if let CheckLintNameResult::Tool(Err((None, _))) = lint_store.check_lint_name(
|
||||||
|
&name.as_str(),
|
||||||
|
Some(tool_name.as_str()),
|
||||||
|
);
|
||||||
|
then {
|
||||||
|
span_lint_and_then(
|
||||||
|
cx,
|
||||||
|
UNKNOWN_CLIPPY_LINTS,
|
||||||
|
lint.span,
|
||||||
|
&format!("unknown clippy lint: clippy::{}", name),
|
||||||
|
|db| {
|
||||||
|
if name.as_str().chars().any(|c| c.is_uppercase()) {
|
||||||
|
let name_lower = name.as_str().to_lowercase().to_string();
|
||||||
|
match lint_store.check_lint_name(
|
||||||
|
&name_lower,
|
||||||
|
Some(tool_name.as_str())
|
||||||
|
) {
|
||||||
|
CheckLintNameResult::NoLint => (),
|
||||||
|
_ => {
|
||||||
|
db.span_suggestion(lint.span,
|
||||||
|
"lowercase the lint name",
|
||||||
|
name_lower);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_relevant_item(tcx: TyCtxt<'_, '_, '_>, item: &Item) -> bool {
|
fn is_relevant_item(tcx: TyCtxt<'_, '_, '_>, item: &Item) -> bool {
|
||||||
if let ItemKind::Fn(_, _, _, eid) = item.node {
|
if let ItemKind::Fn(_, _, _, eid) = item.node {
|
||||||
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)
|
is_relevant_expr(tcx, tcx.body_tables(eid), &tcx.hir.body(eid).value)
|
||||||
|
@ -533,6 +533,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||||||
assign_ops::ASSIGN_OP_PATTERN,
|
assign_ops::ASSIGN_OP_PATTERN,
|
||||||
assign_ops::MISREFACTORED_ASSIGN_OP,
|
assign_ops::MISREFACTORED_ASSIGN_OP,
|
||||||
attrs::DEPRECATED_SEMVER,
|
attrs::DEPRECATED_SEMVER,
|
||||||
|
attrs::UNKNOWN_CLIPPY_LINTS,
|
||||||
attrs::USELESS_ATTRIBUTE,
|
attrs::USELESS_ATTRIBUTE,
|
||||||
bit_mask::BAD_BIT_MASK,
|
bit_mask::BAD_BIT_MASK,
|
||||||
bit_mask::INEFFECTIVE_BIT_MASK,
|
bit_mask::INEFFECTIVE_BIT_MASK,
|
||||||
@ -749,6 +750,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
|
|||||||
|
|
||||||
reg.register_lint_group("clippy::style", Some("clippy_style"), vec![
|
reg.register_lint_group("clippy::style", Some("clippy_style"), vec![
|
||||||
assign_ops::ASSIGN_OP_PATTERN,
|
assign_ops::ASSIGN_OP_PATTERN,
|
||||||
|
attrs::UNKNOWN_CLIPPY_LINTS,
|
||||||
bit_mask::VERBOSE_BIT_MASK,
|
bit_mask::VERBOSE_BIT_MASK,
|
||||||
blacklisted_name::BLACKLISTED_NAME,
|
blacklisted_name::BLACKLISTED_NAME,
|
||||||
block_in_if_condition::BLOCK_IN_IF_CONDITION_EXPR,
|
block_in_if_condition::BLOCK_IN_IF_CONDITION_EXPR,
|
||||||
|
16
tests/ui/unknown_clippy_lints.rs
Normal file
16
tests/ui/unknown_clippy_lints.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
#![allow(clippy::All)]
|
||||||
|
#![warn(clippy::pedantic)]
|
||||||
|
|
||||||
|
#[warn(clippy::if_not_els)]
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
16
tests/ui/unknown_clippy_lints.stderr
Normal file
16
tests/ui/unknown_clippy_lints.stderr
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
error: unknown clippy lint: clippy::if_not_els
|
||||||
|
--> $DIR/unknown_clippy_lints.rs:13:8
|
||||||
|
|
|
||||||
|
13 | #[warn(clippy::if_not_els)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: `-D clippy::unknown-clippy-lints` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: unknown clippy lint: clippy::All
|
||||||
|
--> $DIR/unknown_clippy_lints.rs:10:10
|
||||||
|
|
|
||||||
|
10 | #![allow(clippy::All)]
|
||||||
|
| ^^^^^^^^^^^ help: lowercase the lint name: `all`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user