Auto merge of #6081 - ilknarf:master, r=matthiaskrgr
New Lint: disallowed_method Fixes https://github.com/rust-lang/rust-clippy/issues/6073 I added a `disallowed_method` lint that works similar to `blacklisted_name`, e.g allows config-defined disallowed method calls. This lint allows advanced users to patch in undesired method calls for specific projects. It basically uses the DefId of method calls and matches it to parsed strings. Is there an alternative approach that could use more easily digestible configuration strings? All tests pass as expected except for a linting error on `ui/redundant_pattern_matching_option`, which I am not sure how to resolve since I don't think I changed anything affecting it. changelog: Add disallowed_method lint to warn on user-defined method calls
This commit is contained in:
commit
ea079eb8a4
10 changed files with 121 additions and 2 deletions
|
|
@ -1559,6 +1559,7 @@ Released 2018-09-13
|
|||
[`deref_addrof`]: https://rust-lang.github.io/rust-clippy/master/index.html#deref_addrof
|
||||
[`derive_hash_xor_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_hash_xor_eq
|
||||
[`derive_ord_xor_partial_ord`]: https://rust-lang.github.io/rust-clippy/master/index.html#derive_ord_xor_partial_ord
|
||||
[`disallowed_method`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_method
|
||||
[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
|
||||
[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
|
||||
[`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
|
||||
|
||||
[There are over 350 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
|
||||
[There are over 400 lints included in this crate!](https://rust-lang.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:
|
||||
|
||||
|
|
|
|||
73
clippy_lints/src/disallowed_method.rs
Normal file
73
clippy_lints/src/disallowed_method.rs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
use crate::utils::span_lint;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::{Expr, ExprKind};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::Symbol;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Lints for specific trait methods defined in clippy.toml
|
||||
///
|
||||
/// **Why is this bad?** Some methods are undesirable in certain contexts,
|
||||
/// and it would be beneficial to lint for them as needed.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// // example code where clippy issues a warning
|
||||
/// foo.bad_method(); // Foo::bad_method is disallowed in the configuration
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust,ignore
|
||||
/// // example code which does not raise clippy warning
|
||||
/// goodStruct.bad_method(); // GoodStruct::bad_method is not disallowed
|
||||
/// ```
|
||||
pub DISALLOWED_METHOD,
|
||||
nursery,
|
||||
"use of a disallowed method call"
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DisallowedMethod {
|
||||
disallowed: FxHashSet<Vec<Symbol>>,
|
||||
}
|
||||
|
||||
impl DisallowedMethod {
|
||||
pub fn new(disallowed: &FxHashSet<String>) -> Self {
|
||||
Self {
|
||||
disallowed: disallowed
|
||||
.iter()
|
||||
.map(|s| s.split("::").map(|seg| Symbol::intern(seg)).collect::<Vec<_>>())
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_lint_pass!(DisallowedMethod => [DISALLOWED_METHOD]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for DisallowedMethod {
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::MethodCall(_path, _, _args, _) = &expr.kind {
|
||||
let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
|
||||
|
||||
let method_call = cx.get_def_path(def_id);
|
||||
if self.disallowed.contains(&method_call) {
|
||||
let method = method_call
|
||||
.iter()
|
||||
.map(|s| s.to_ident_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join("::");
|
||||
|
||||
span_lint(
|
||||
cx,
|
||||
DISALLOWED_METHOD,
|
||||
expr.span,
|
||||
&format!("use of a disallowed method `{}`", method),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -175,6 +175,7 @@ mod dbg_macro;
|
|||
mod default_trait_access;
|
||||
mod dereference;
|
||||
mod derive;
|
||||
mod disallowed_method;
|
||||
mod doc;
|
||||
mod double_comparison;
|
||||
mod double_parens;
|
||||
|
|
@ -525,6 +526,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
&derive::DERIVE_ORD_XOR_PARTIAL_ORD,
|
||||
&derive::EXPL_IMPL_CLONE_ON_COPY,
|
||||
&derive::UNSAFE_DERIVE_DESERIALIZE,
|
||||
&disallowed_method::DISALLOWED_METHOD,
|
||||
&doc::DOC_MARKDOWN,
|
||||
&doc::MISSING_ERRORS_DOC,
|
||||
&doc::MISSING_SAFETY_DOC,
|
||||
|
|
@ -1118,6 +1120,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|| box async_yields_async::AsyncYieldsAsync);
|
||||
store.register_late_pass(|| box manual_strip::ManualStrip);
|
||||
store.register_late_pass(|| box utils::internal_lints::MatchTypeOnDiagItem);
|
||||
let disallowed_methods = conf.disallowed_methods.iter().cloned().collect::<FxHashSet<_>>();
|
||||
store.register_late_pass(move || box disallowed_method::DisallowedMethod::new(&disallowed_methods));
|
||||
|
||||
|
||||
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
|
||||
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
|
||||
|
|
@ -1807,6 +1812,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
|
||||
LintId::of(&attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
|
||||
LintId::of(&cognitive_complexity::COGNITIVE_COMPLEXITY),
|
||||
LintId::of(&disallowed_method::DISALLOWED_METHOD),
|
||||
LintId::of(&fallible_impl_from::FALLIBLE_IMPL_FROM),
|
||||
LintId::of(&floating_point_arithmetic::IMPRECISE_FLOPS),
|
||||
LintId::of(&floating_point_arithmetic::SUBOPTIMAL_FLOPS),
|
||||
|
|
|
|||
|
|
@ -164,6 +164,8 @@ define_Conf! {
|
|||
(max_fn_params_bools, "max_fn_params_bools": u64, 3),
|
||||
/// Lint: WILDCARD_IMPORTS. Whether to allow certain wildcard imports (prelude, super in tests).
|
||||
(warn_on_all_wildcard_imports, "warn_on_all_wildcard_imports": bool, false),
|
||||
/// Lint: DISALLOWED_METHOD. The list of blacklisted methods to lint about. NB: `bar` is not here since it has legitimate uses
|
||||
(disallowed_methods, "disallowed_methods": Vec<String>, Vec::<String>::new()),
|
||||
}
|
||||
|
||||
impl Default for Conf {
|
||||
|
|
|
|||
|
|
@ -381,6 +381,13 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
|
|||
deprecation: None,
|
||||
module: "derive",
|
||||
},
|
||||
Lint {
|
||||
name: "disallowed_method",
|
||||
group: "nursery",
|
||||
desc: "use of a disallowed method call",
|
||||
deprecation: None,
|
||||
module: "disallowed_method",
|
||||
},
|
||||
Lint {
|
||||
name: "diverging_sub_expression",
|
||||
group: "complexity",
|
||||
|
|
|
|||
1
tests/ui-toml/toml_disallowed_method/clippy.toml
Normal file
1
tests/ui-toml/toml_disallowed_method/clippy.toml
Normal file
|
|
@ -0,0 +1 @@
|
|||
disallowed-methods = ["core::iter::traits::iterator::Iterator::sum", "regex::re_unicode::Regex::is_match"]
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#![warn(clippy::disallowed_method)]
|
||||
|
||||
extern crate regex;
|
||||
use regex::Regex;
|
||||
|
||||
fn main() {
|
||||
let a = vec![1, 2, 3, 4];
|
||||
let re = Regex::new(r"ab.*c").unwrap();
|
||||
|
||||
re.is_match("abc");
|
||||
|
||||
a.iter().sum::<i32>();
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
error: use of a disallowed method `regex::re_unicode::Regex::is_match`
|
||||
--> $DIR/conf_disallowed_method.rs:10:5
|
||||
|
|
||||
LL | re.is_match("abc");
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `-D clippy::disallowed-method` implied by `-D warnings`
|
||||
|
||||
error: use of a disallowed method `core::iter::traits::iterator::Iterator::sum`
|
||||
--> $DIR/conf_disallowed_method.rs:12:5
|
||||
|
|
||||
LL | a.iter().sum::<i32>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `third-party` at line 5 column 1
|
||||
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `third-party` at line 5 column 1
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue