diff options
| author | bors <bors@rust-lang.org> | 2020-01-29 16:29:05 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-01-29 16:29:05 +0000 |
| commit | f69835bab7cfa56dc4565d8fe32765a95d93182b (patch) | |
| tree | a974f2bcbe87f3190fc7c2b6d64271c7a99c5221 | |
| parent | c0f39cfb466202a1dbe8368ca177848083dc34cb (diff) | |
| parent | ac9f019fbf68631eb947c3b7fcc5563c3506d040 (diff) | |
| download | rust-f69835bab7cfa56dc4565d8fe32765a95d93182b.tar.gz rust-f69835bab7cfa56dc4565d8fe32765a95d93182b.zip | |
Auto merge of #5058 - xiongmao86:issue4903, r=flip1995
Closes Issue4903 fixes #4903. Check list: - [x] Followed [lint naming conventions][lint_naming] - [x] Added passing UI tests (including committed `.stderr` file) - [x] `cargo test` passes locally - [x] Executed `./util/dev update_lints` - [x] Added lint documentation - [x] Run `./util/dev fmt` [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints --- changelog: implement lint that warn about single component path imports(`use ident;`).
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.rs | 5 | ||||
| -rw-r--r-- | clippy_lints/src/methods/mod.rs | 8 | ||||
| -rw-r--r-- | clippy_lints/src/single_component_path_imports.rs | 61 | ||||
| -rw-r--r-- | clippy_lints/src/types.rs | 2 | ||||
| -rw-r--r-- | src/lintlist/mod.rs | 9 | ||||
| -rw-r--r-- | tests/ui/single_component_path_imports.fixed | 12 | ||||
| -rw-r--r-- | tests/ui/single_component_path_imports.rs | 12 | ||||
| -rw-r--r-- | tests/ui/single_component_path_imports.stderr | 10 |
10 files changed, 115 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 78020c2dac6..d5dbbabb3c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1284,6 +1284,7 @@ Released 2018-09-13 [`should_implement_trait`]: https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait [`similar_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#similar_names [`single_char_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_char_pattern +[`single_component_path_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_component_path_imports [`single_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match [`single_match_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else [`skip_while_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#skip_while_next diff --git a/README.md b/README.md index 8f65ff94ca8..0cb14eda6a8 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are 349 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are 350 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: diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 91240362445..7008c6d6839 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -284,6 +284,7 @@ pub mod replace_consts; pub mod returns; pub mod serde_api; pub mod shadow; +pub mod single_component_path_imports; pub mod slow_vector_initialization; pub mod strings; pub mod suspicious_trait_impl; @@ -741,6 +742,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &shadow::SHADOW_REUSE, &shadow::SHADOW_SAME, &shadow::SHADOW_UNRELATED, + &single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS, &slow_vector_initialization::SLOW_VECTOR_INITIALIZATION, &strings::STRING_ADD, &strings::STRING_ADD_ASSIGN, @@ -993,6 +995,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_early_pass(|| box utils::internal_lints::ProduceIce); store.register_late_pass(|| box let_underscore::LetUnderscore); store.register_late_pass(|| box atomic_ordering::AtomicOrdering); + store.register_early_pass(|| box single_component_path_imports::SingleComponentPathImports); store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![ LintId::of(&arithmetic::FLOAT_ARITHMETIC), @@ -1296,6 +1299,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&returns::NEEDLESS_RETURN), LintId::of(&returns::UNUSED_UNIT), LintId::of(&serde_api::SERDE_API_MISUSE), + LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS), LintId::of(&slow_vector_initialization::SLOW_VECTOR_INITIALIZATION), LintId::of(&strings::STRING_LIT_AS_BYTES), LintId::of(&suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL), @@ -1431,6 +1435,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: LintId::of(&returns::LET_AND_RETURN), LintId::of(&returns::NEEDLESS_RETURN), LintId::of(&returns::UNUSED_UNIT), + LintId::of(&single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS), LintId::of(&strings::STRING_LIT_AS_BYTES), LintId::of(&tabs_in_doc_comments::TABS_IN_DOC_COMMENTS), LintId::of(&to_digit_is_some::TO_DIGIT_IS_SOME), diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index d00d8dfbd3e..6e5015eb844 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -2310,7 +2310,7 @@ fn lint_unwrap(cx: &LateContext<'_, '_>, expr: &hir::Expr<'_>, unwrap_args: &[hi &format!("used `unwrap()` on `{}` value", kind,), &format!( "if you don't want to handle the `{}` case gracefully, consider \ - using `expect()` to provide a better panic message", + using `expect()` to provide a better panic message", none_value, ), ); @@ -2679,7 +2679,7 @@ fn lint_filter_flat_map<'a, 'tcx>( if match_trait_method(cx, expr, &paths::ITERATOR) { let msg = "called `filter(p).flat_map(q)` on an `Iterator`"; let hint = "this is more succinctly expressed by calling `.flat_map(..)` \ - and filtering by returning `iter::empty()`"; + and filtering by returning `iter::empty()`"; span_lint_and_help(cx, FILTER_MAP, expr.span, msg, hint); } } @@ -2695,7 +2695,7 @@ fn lint_filter_map_flat_map<'a, 'tcx>( if match_trait_method(cx, expr, &paths::ITERATOR) { let msg = "called `filter_map(p).flat_map(q)` on an `Iterator`"; let hint = "this is more succinctly expressed by calling `.flat_map(..)` \ - and filtering by returning `iter::empty()`"; + and filtering by returning `iter::empty()`"; span_lint_and_help(cx, FILTER_MAP, expr.span, msg, hint); } } @@ -3148,7 +3148,7 @@ fn lint_option_as_ref_deref<'a, 'tcx>( let msg = format!( "called `{0}` (or with one of deref aliases) on an Option value. \ - This can be done more directly by calling `{1}` instead", + This can be done more directly by calling `{1}` instead", current_method, hint ); span_lint_and_sugg( diff --git a/clippy_lints/src/single_component_path_imports.rs b/clippy_lints/src/single_component_path_imports.rs new file mode 100644 index 00000000000..eb3261bebe3 --- /dev/null +++ b/clippy_lints/src/single_component_path_imports.rs @@ -0,0 +1,61 @@ +use crate::utils::span_lint_and_sugg; +use if_chain::if_chain; +use rustc_errors::Applicability; +use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::edition::Edition; +use syntax::ast::{Item, ItemKind, UseTreeKind}; + +declare_clippy_lint! { + /// **What it does:** Checking for imports with single component use path. + /// + /// **Why is this bad?** Import with single component use path such as `use cratename;` + /// is not necessary, and thus should be removed. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// + /// ```rust, ignore + /// use regex; + /// + /// fn main() { + /// regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap(); + /// } + /// ``` + /// Better as + /// ```rust, ignore + /// fn main() { + /// regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap(); + /// } + /// ``` + pub SINGLE_COMPONENT_PATH_IMPORTS, + style, + "imports with single component path are redundant" +} + +declare_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]); + +impl EarlyLintPass for SingleComponentPathImports { + fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { + if_chain! { + if cx.sess.opts.edition == Edition::Edition2018; + if !item.vis.node.is_pub(); + if let ItemKind::Use(use_tree) = &item.kind; + if let segments = &use_tree.prefix.segments; + if segments.len() == 1; + if let UseTreeKind::Simple(None, _, _) = use_tree.kind; + then { + span_lint_and_sugg( + cx, + SINGLE_COMPONENT_PATH_IMPORTS, + item.span, + "this import is redundant", + "remove it entirely", + String::new(), + Applicability::MachineApplicable + ); + } + } + } +} diff --git a/clippy_lints/src/types.rs b/clippy_lints/src/types.rs index 4fcf39d2142..e47f2480a54 100644 --- a/clippy_lints/src/types.rs +++ b/clippy_lints/src/types.rs @@ -316,7 +316,7 @@ impl Types { OPTION_OPTION, hir_ty.span, "consider using `Option<T>` instead of `Option<Option<T>>` or a custom \ - enum if you need to distinguish all 3 cases", + enum if you need to distinguish all 3 cases", ); return; // don't recurse into the type } diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs index 5dbcb4483f2..b762c8d1395 100644 --- a/src/lintlist/mod.rs +++ b/src/lintlist/mod.rs @@ -6,7 +6,7 @@ pub use lint::Lint; pub use lint::LINT_LEVELS; // begin lint list, do not remove this comment, it’s used in `update_lints` -pub const ALL_LINTS: [Lint; 349] = [ +pub const ALL_LINTS: [Lint; 350] = [ Lint { name: "absurd_extreme_comparisons", group: "correctness", @@ -1856,6 +1856,13 @@ pub const ALL_LINTS: [Lint; 349] = [ module: "methods", }, Lint { + name: "single_component_path_imports", + group: "style", + desc: "imports with single component path are redundant", + deprecation: None, + module: "single_component_path_imports", + }, + Lint { name: "single_match", group: "style", desc: "a `match` statement with a single nontrivial arm (i.e., where the other arm is `_ => {}`) instead of `if let`", diff --git a/tests/ui/single_component_path_imports.fixed b/tests/ui/single_component_path_imports.fixed new file mode 100644 index 00000000000..7a882efc4d1 --- /dev/null +++ b/tests/ui/single_component_path_imports.fixed @@ -0,0 +1,12 @@ +// run-rustfix +// compile-flags: --edition 2018 +#![warn(clippy::single_component_path_imports)] +#![allow(unused_imports)] + + +use serde as edres; +pub use serde; + +fn main() { + regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap(); +} diff --git a/tests/ui/single_component_path_imports.rs b/tests/ui/single_component_path_imports.rs new file mode 100644 index 00000000000..d084425cd70 --- /dev/null +++ b/tests/ui/single_component_path_imports.rs @@ -0,0 +1,12 @@ +// run-rustfix +// compile-flags: --edition 2018 +#![warn(clippy::single_component_path_imports)] +#![allow(unused_imports)] + +use regex; +use serde as edres; +pub use serde; + +fn main() { + regex::Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap(); +} diff --git a/tests/ui/single_component_path_imports.stderr b/tests/ui/single_component_path_imports.stderr new file mode 100644 index 00000000000..519ada0169a --- /dev/null +++ b/tests/ui/single_component_path_imports.stderr @@ -0,0 +1,10 @@ +error: this import is redundant + --> $DIR/single_component_path_imports.rs:6:1 + | +LL | use regex; + | ^^^^^^^^^^ help: remove it entirely + | + = note: `-D clippy::single-component-path-imports` implied by `-D warnings` + +error: aborting due to previous error + |
