Skip to content

Commit 045b411

Browse files
committed
add configuration for [wildcard_imports] to ignore certain imports
1 parent 7e650b7 commit 045b411

File tree

8 files changed

+78
-3
lines changed

8 files changed

+78
-3
lines changed

clippy_config/src/conf.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,11 @@ define_Conf! {
547547
///
548548
/// Whether to also run the listed lints on private items.
549549
(check_private_items: bool = false),
550+
/// Lint: WILDCARD_IMPORTS.
551+
///
552+
/// List of path segments to ignore when checking wildcard imports,
553+
/// could get overrided by `warn_on_all_wildcard_imports`.
554+
(ignored_wildcard_imports: Vec<String> = Vec::new()),
550555
}
551556

552557
/// Search for the configuration file.

clippy_lints/src/lib.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
539539
excessive_nesting_threshold,
540540
future_size_threshold,
541541
ref ignore_interior_mutability,
542+
ref ignored_wildcard_imports,
542543
large_error_threshold,
543544
literal_representation_threshold,
544545
matches_for_let_else,
@@ -867,7 +868,12 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
867868
))
868869
});
869870
store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap));
870-
store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
871+
store.register_late_pass(move |_| {
872+
Box::new(wildcard_imports::WildcardImports::new(
873+
warn_on_all_wildcard_imports,
874+
ignored_wildcard_imports.clone(),
875+
))
876+
});
871877
store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
872878
store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
873879
store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());

clippy_lints/src/wildcard_imports.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::is_test_module_or_function;
33
use clippy_utils::source::{snippet, snippet_with_applicability};
4+
use rustc_data_structures::fx::FxHashSet;
45
use rustc_errors::Applicability;
56
use rustc_hir::def::{DefKind, Res};
67
use rustc_hir::{Item, ItemKind, PathSegment, UseKind};
@@ -100,13 +101,15 @@ declare_clippy_lint! {
100101
pub struct WildcardImports {
101102
warn_on_all: bool,
102103
test_modules_deep: u32,
104+
ignored_segments: Vec<String>,
103105
}
104106

105107
impl WildcardImports {
106-
pub fn new(warn_on_all: bool) -> Self {
108+
pub fn new(warn_on_all: bool, ignored_wildcard_imports: Vec<String>) -> Self {
107109
Self {
108110
warn_on_all,
109111
test_modules_deep: 0,
112+
ignored_segments: ignored_wildcard_imports,
110113
}
111114
}
112115
}
@@ -190,6 +193,7 @@ impl WildcardImports {
190193
item.span.from_expansion()
191194
|| is_prelude_import(segments)
192195
|| (is_super_only_import(segments) && self.test_modules_deep > 0)
196+
|| is_ignored_via_config(segments, &self.ignored_segments)
193197
}
194198
}
195199

@@ -198,10 +202,20 @@ impl WildcardImports {
198202
fn is_prelude_import(segments: &[PathSegment<'_>]) -> bool {
199203
segments
200204
.iter()
201-
.any(|ps| ps.ident.name.as_str().contains(sym::prelude.as_str()))
205+
.any(|ps| ps.ident.as_str().contains(sym::prelude.as_str()))
202206
}
203207

204208
// Allow "super::*" imports in tests.
205209
fn is_super_only_import(segments: &[PathSegment<'_>]) -> bool {
206210
segments.len() == 1 && segments[0].ident.name == kw::Super
207211
}
212+
213+
// Allow skipping imports containing user configured segments,
214+
// i.e. "...::utils::...::*" if user put `ignored-wildcard-imports = ["utils"]` in `Clippy.toml`
215+
fn is_ignored_via_config(segments: &[PathSegment<'_>], ignored_segments: &[String]) -> bool {
216+
let segments_set: FxHashSet<&str> = segments.iter().map(|s| s.ident.as_str()).collect();
217+
let ignored_set: FxHashSet<&str> = ignored_segments.iter().map(String::as_str).collect();
218+
// segment matching need to be exact instead of using 'contains', in case user unintentionaly put
219+
// a single character in the config thus skipping most of the warnings.
220+
segments_set.intersection(&ignored_set).next().is_some()
221+
}

tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
3737
excessive-nesting-threshold
3838
future-size-threshold
3939
ignore-interior-mutability
40+
ignored-wildcard-imports
4041
large-error-threshold
4142
literal-representation-threshold
4243
matches-for-let-else
@@ -112,6 +113,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
112113
excessive-nesting-threshold
113114
future-size-threshold
114115
ignore-interior-mutability
116+
ignored-wildcard-imports
115117
large-error-threshold
116118
literal-representation-threshold
117119
matches-for-let-else
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ignored-wildcard-imports = ["utils"]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![warn(clippy::wildcard_imports)]
2+
3+
mod utils {
4+
pub fn print() {}
5+
}
6+
7+
mod utils_plus {
8+
pub fn do_something() {}
9+
}
10+
11+
use utils::*;
12+
use utils_plus::do_something;
13+
//~^ ERROR: usage of wildcard import
14+
15+
fn main() {
16+
print();
17+
do_something();
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![warn(clippy::wildcard_imports)]
2+
3+
mod utils {
4+
pub fn print() {}
5+
}
6+
7+
mod utils_plus {
8+
pub fn do_something() {}
9+
}
10+
11+
use utils::*;
12+
use utils_plus::*;
13+
//~^ ERROR: usage of wildcard import
14+
15+
fn main() {
16+
print();
17+
do_something();
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: usage of wildcard import
2+
--> $DIR/wildcard_imports.rs:12:5
3+
|
4+
LL | use utils_plus::*;
5+
| ^^^^^^^^^^^^^ help: try: `utils_plus::do_something`
6+
|
7+
= note: `-D clippy::wildcard-imports` implied by `-D warnings`
8+
= help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
9+
10+
error: aborting due to 1 previous error
11+

0 commit comments

Comments
 (0)