Skip to content

Commit 9ecb70a

Browse files
committed
Fix FP in single_component_path_imports lint
1 parent 65d046c commit 9ecb70a

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

clippy_lints/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
12311231
store.register_early_pass(|| box as_conversions::AsConversions);
12321232
store.register_late_pass(|| box let_underscore::LetUnderscore);
12331233
store.register_late_pass(|| box atomic_ordering::AtomicOrdering);
1234-
store.register_early_pass(|| box single_component_path_imports::SingleComponentPathImports);
1234+
store.register_early_pass(|| box single_component_path_imports::SingleComponentPathImports::default());
12351235
let max_fn_params_bools = conf.max_fn_params_bools;
12361236
let max_struct_bools = conf.max_struct_bools;
12371237
store.register_early_pass(move || box excessive_bools::ExcessiveBools::new(max_struct_bools, max_fn_params_bools));

clippy_lints/src/single_component_path_imports.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use if_chain::if_chain;
33
use rustc_ast::{Item, ItemKind, UseTreeKind};
44
use rustc_errors::Applicability;
55
use rustc_lint::{EarlyContext, EarlyLintPass};
6-
use rustc_session::{declare_lint_pass, declare_tool_lint};
6+
use rustc_session::{declare_tool_lint, impl_lint_pass};
77
use rustc_span::edition::Edition;
8+
use rustc_span::symbol::{kw, Symbol};
89

910
declare_clippy_lint! {
1011
/// **What it does:** Checking for imports with single component use path.
@@ -34,10 +35,50 @@ declare_clippy_lint! {
3435
"imports with single component path are redundant"
3536
}
3637

37-
declare_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]);
38+
#[derive(Default)]
39+
pub struct SingleComponentPathImports {
40+
/// detect imports reused with `self` keyword,
41+
/// such as `self::crypto_hash` in the example below
42+
///
43+
/// ```rust,ignore
44+
/// use self::crypto_hash::{Algorithm, Hasher};
45+
/// use crypto_hash;
46+
/// ```
47+
imports_as_use_self: Vec<Symbol>,
48+
}
49+
50+
impl_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]);
3851

3952
impl EarlyLintPass for SingleComponentPathImports {
4053
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
54+
if_chain! {
55+
if !in_macro(item.span);
56+
if cx.sess.opts.edition >= Edition::Edition2018;
57+
if let ItemKind::Use(use_tree) = &item.kind;
58+
if let segments = &use_tree.prefix.segments;
59+
if segments[0].ident.name == kw::SelfLower;
60+
61+
then {
62+
// simple case such as `use self::module::SomeStruct`
63+
if segments.len() > 1 {
64+
self.imports_as_use_self.push(segments[1].ident.name);
65+
return;
66+
}
67+
68+
// nested case such as `use self::{module1::Struct1, module2::Struct2}`
69+
if let UseTreeKind::Nested(trees) = &use_tree.kind {
70+
for tree in trees {
71+
let segments = &tree.0.prefix.segments;
72+
if !segments.is_empty() {
73+
self.imports_as_use_self.push(segments[0].ident.name);
74+
}
75+
}
76+
}
77+
}
78+
}
79+
}
80+
81+
fn check_item_post(&mut self, cx: &EarlyContext<'_>, item: &Item) {
4182
if_chain! {
4283
if !in_macro(item.span);
4384
if cx.sess.opts.edition >= Edition::Edition2018;
@@ -46,6 +87,8 @@ impl EarlyLintPass for SingleComponentPathImports {
4687
if let segments = &use_tree.prefix.segments;
4788
if segments.len() == 1;
4889
if let UseTreeKind::Simple(None, _, _) = use_tree.kind;
90+
if !self.imports_as_use_self.contains(&segments[0].ident.name);
91+
4992
then {
5093
span_lint_and_sugg(
5194
cx,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// edition:2018
2+
#![warn(clippy::single_component_path_imports)]
3+
#![allow(unused_imports)]
4+
5+
use self::regex::{Regex as xeger, RegexSet as tesxeger};
6+
pub use self::{
7+
regex::{Regex, RegexSet},
8+
some_mod::SomeType,
9+
};
10+
use regex;
11+
12+
mod some_mod {
13+
pub struct SomeType;
14+
}
15+
16+
fn main() {}

0 commit comments

Comments
 (0)