diff options
| -rw-r--r-- | clippy_lints/src/single_component_path_imports.rs | 73 | ||||
| -rw-r--r-- | tests/ui/single_component_path_imports_nested_first.rs | 17 | ||||
| -rw-r--r-- | tests/ui/single_component_path_imports_nested_first.stderr | 25 |
3 files changed, 92 insertions, 23 deletions
diff --git a/clippy_lints/src/single_component_path_imports.rs b/clippy_lints/src/single_component_path_imports.rs index adf0d7998f8..6104103580e 100644 --- a/clippy_lints/src/single_component_path_imports.rs +++ b/clippy_lints/src/single_component_path_imports.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; use clippy_utils::in_macro; use rustc_ast::{ptr::P, Crate, Item, ItemKind, ModKind, UseTreeKind}; use rustc_errors::Applicability; @@ -66,15 +66,27 @@ fn check_mod(cx: &EarlyContext<'_>, items: &[P<Item>]) { for single_use in &single_use_usages { if !imports_reused_with_self.contains(&single_use.0) { - span_lint_and_sugg( - cx, - SINGLE_COMPONENT_PATH_IMPORTS, - single_use.1, - "this import is redundant", - "remove it entirely", - String::new(), - Applicability::MachineApplicable, - ); + let can_suggest = single_use.2; + if can_suggest { + span_lint_and_sugg( + cx, + SINGLE_COMPONENT_PATH_IMPORTS, + single_use.1, + "this import is redundant", + "remove it entirely", + String::new(), + Applicability::MachineApplicable, + ); + } else { + span_lint_and_help( + cx, + SINGLE_COMPONENT_PATH_IMPORTS, + single_use.1, + "this import is redundant", + None, + "remove this import", + ); + } } } } @@ -83,7 +95,7 @@ fn track_uses( cx: &EarlyContext<'_>, item: &Item, imports_reused_with_self: &mut Vec<Symbol>, - single_use_usages: &mut Vec<(Symbol, Span)>, + single_use_usages: &mut Vec<(Symbol, Span, bool)>, ) { if in_macro(item.span) || item.vis.kind.is_pub() { return; @@ -100,25 +112,40 @@ fn track_uses( if segments.len() == 1 { if let UseTreeKind::Simple(None, _, _) = use_tree.kind { let ident = &segments[0].ident; - single_use_usages.push((ident.name, item.span)); + single_use_usages.push((ident.name, item.span, true)); } return; } - // keep track of `use self::some_module` usages - if segments[0].ident.name == kw::SelfLower { - // simple case such as `use self::module::SomeStruct` - if segments.len() > 1 { - imports_reused_with_self.push(segments[1].ident.name); - return; - } - - // nested case such as `use self::{module1::Struct1, module2::Struct2}` + if segments.is_empty() { + // keep track of `use {some_module, some_other_module};` usages if let UseTreeKind::Nested(trees) = &use_tree.kind { for tree in trees { let segments = &tree.0.prefix.segments; - if !segments.is_empty() { - imports_reused_with_self.push(segments[0].ident.name); + if segments.len() == 1 { + if let UseTreeKind::Simple(None, _, _) = tree.0.kind { + let ident = &segments[0].ident; + single_use_usages.push((ident.name, tree.0.span, false)); + } + } + } + } + } else { + // keep track of `use self::some_module` usages + if segments[0].ident.name == kw::SelfLower { + // simple case such as `use self::module::SomeStruct` + if segments.len() > 1 { + imports_reused_with_self.push(segments[1].ident.name); + return; + } + + // nested case such as `use self::{module1::Struct1, module2::Struct2}` + if let UseTreeKind::Nested(trees) = &use_tree.kind { + for tree in trees { + let segments = &tree.0.prefix.segments; + if !segments.is_empty() { + imports_reused_with_self.push(segments[0].ident.name); + } } } } diff --git a/tests/ui/single_component_path_imports_nested_first.rs b/tests/ui/single_component_path_imports_nested_first.rs new file mode 100644 index 00000000000..94117061b27 --- /dev/null +++ b/tests/ui/single_component_path_imports_nested_first.rs @@ -0,0 +1,17 @@ +// 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(); +} + +mod root_nested_use_mod { + use {regex, serde}; + #[allow(dead_code)] + fn root_nested_use_mod() {} +} diff --git a/tests/ui/single_component_path_imports_nested_first.stderr b/tests/ui/single_component_path_imports_nested_first.stderr new file mode 100644 index 00000000000..0c3256c1ce4 --- /dev/null +++ b/tests/ui/single_component_path_imports_nested_first.stderr @@ -0,0 +1,25 @@ +error: this import is redundant + --> $DIR/single_component_path_imports_nested_first.rs:14:10 + | +LL | use {regex, serde}; + | ^^^^^ + | + = note: `-D clippy::single-component-path-imports` implied by `-D warnings` + = help: remove this import + +error: this import is redundant + --> $DIR/single_component_path_imports_nested_first.rs:14:17 + | +LL | use {regex, serde}; + | ^^^^^ + | + = help: remove this import + +error: this import is redundant + --> $DIR/single_component_path_imports_nested_first.rs:5:1 + | +LL | use regex; + | ^^^^^^^^^^ help: remove it entirely + +error: aborting due to 3 previous errors + |
