diff options
| -rw-r--r-- | clippy_config/src/conf.rs | 5 | ||||
| -rw-r--r-- | clippy_lints/src/lib.rs | 8 | ||||
| -rw-r--r-- | clippy_lints/src/wildcard_imports.rs | 18 | ||||
| -rw-r--r-- | tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr | 2 | ||||
| -rw-r--r-- | tests/ui-toml/wildcard_imports_whitelist/clippy.toml | 1 | ||||
| -rw-r--r-- | tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed | 18 | ||||
| -rw-r--r-- | tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs | 18 | ||||
| -rw-r--r-- | tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr | 11 |
8 files changed, 78 insertions, 3 deletions
diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs index 8b45f250b10..e4e512482ac 100644 --- a/clippy_config/src/conf.rs +++ b/clippy_config/src/conf.rs @@ -571,6 +571,11 @@ define_Conf! { /// /// Don't lint when comparing the result of a modulo operation to zero. (allow_comparison_to_zero: bool = true), + /// Lint: WILDCARD_IMPORTS. + /// + /// List of path segments to ignore when checking wildcard imports, + /// could get overrided by `warn_on_all_wildcard_imports`. + (ignored_wildcard_imports: Vec<String> = Vec::new()), } /// Search for the configuration file. diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 7da916ade2a..678058a5411 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -545,6 +545,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { excessive_nesting_threshold, future_size_threshold, ref ignore_interior_mutability, + ref ignored_wildcard_imports, large_error_threshold, literal_representation_threshold, matches_for_let_else, @@ -876,7 +877,12 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { )) }); store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap)); - store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports))); + store.register_late_pass(move |_| { + Box::new(wildcard_imports::WildcardImports::new( + warn_on_all_wildcard_imports, + ignored_wildcard_imports.clone(), + )) + }); store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default()); store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress)); store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default()); diff --git a/clippy_lints/src/wildcard_imports.rs b/clippy_lints/src/wildcard_imports.rs index b82bd1d7e7c..4eb45e6f8da 100644 --- a/clippy_lints/src/wildcard_imports.rs +++ b/clippy_lints/src/wildcard_imports.rs @@ -1,6 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::is_test_module_or_function; use clippy_utils::source::{snippet, snippet_with_applicability}; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::{Item, ItemKind, PathSegment, UseKind}; @@ -100,13 +101,15 @@ declare_clippy_lint! { pub struct WildcardImports { warn_on_all: bool, test_modules_deep: u32, + ignored_segments: Vec<String>, } impl WildcardImports { - pub fn new(warn_on_all: bool) -> Self { + pub fn new(warn_on_all: bool, ignored_wildcard_imports: Vec<String>) -> Self { Self { warn_on_all, test_modules_deep: 0, + ignored_segments: ignored_wildcard_imports, } } } @@ -190,6 +193,7 @@ impl WildcardImports { item.span.from_expansion() || is_prelude_import(segments) || (is_super_only_import(segments) && self.test_modules_deep > 0) + || is_ignored_via_config(segments, &self.ignored_segments) } } @@ -198,10 +202,20 @@ impl WildcardImports { fn is_prelude_import(segments: &[PathSegment<'_>]) -> bool { segments .iter() - .any(|ps| ps.ident.name.as_str().contains(sym::prelude.as_str())) + .any(|ps| ps.ident.as_str().contains(sym::prelude.as_str())) } // Allow "super::*" imports in tests. fn is_super_only_import(segments: &[PathSegment<'_>]) -> bool { segments.len() == 1 && segments[0].ident.name == kw::Super } + +// Allow skipping imports containing user configured segments, +// i.e. "...::utils::...::*" if user put `ignored-wildcard-imports = ["utils"]` in `Clippy.toml` +fn is_ignored_via_config(segments: &[PathSegment<'_>], ignored_segments: &[String]) -> bool { + let segments_set: FxHashSet<&str> = segments.iter().map(|s| s.ident.as_str()).collect(); + let ignored_set: FxHashSet<&str> = ignored_segments.iter().map(String::as_str).collect(); + // segment matching need to be exact instead of using 'contains', in case user unintentionaly put + // a single character in the config thus skipping most of the warnings. + segments_set.intersection(&ignored_set).next().is_some() +} diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 24fdfd945bd..b1e000abec8 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -39,6 +39,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect excessive-nesting-threshold future-size-threshold ignore-interior-mutability + ignored-wildcard-imports large-error-threshold literal-representation-threshold matches-for-let-else @@ -117,6 +118,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect excessive-nesting-threshold future-size-threshold ignore-interior-mutability + ignored-wildcard-imports large-error-threshold literal-representation-threshold matches-for-let-else diff --git a/tests/ui-toml/wildcard_imports_whitelist/clippy.toml b/tests/ui-toml/wildcard_imports_whitelist/clippy.toml new file mode 100644 index 00000000000..1d28cac588b --- /dev/null +++ b/tests/ui-toml/wildcard_imports_whitelist/clippy.toml @@ -0,0 +1 @@ +ignored-wildcard-imports = ["utils"] diff --git a/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed b/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed new file mode 100644 index 00000000000..5ef30b054b3 --- /dev/null +++ b/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed @@ -0,0 +1,18 @@ +#![warn(clippy::wildcard_imports)] + +mod utils { + pub fn print() {} +} + +mod utils_plus { + pub fn do_something() {} +} + +use utils::*; +use utils_plus::do_something; +//~^ ERROR: usage of wildcard import + +fn main() { + print(); + do_something(); +} diff --git a/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs b/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs new file mode 100644 index 00000000000..5ea91a8d70a --- /dev/null +++ b/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs @@ -0,0 +1,18 @@ +#![warn(clippy::wildcard_imports)] + +mod utils { + pub fn print() {} +} + +mod utils_plus { + pub fn do_something() {} +} + +use utils::*; +use utils_plus::*; +//~^ ERROR: usage of wildcard import + +fn main() { + print(); + do_something(); +} diff --git a/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr b/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr new file mode 100644 index 00000000000..15f522cb5af --- /dev/null +++ b/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr @@ -0,0 +1,11 @@ +error: usage of wildcard import + --> $DIR/wildcard_imports.rs:12:5 + | +LL | use utils_plus::*; + | ^^^^^^^^^^^^^ help: try: `utils_plus::do_something` + | + = note: `-D clippy::wildcard-imports` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]` + +error: aborting due to 1 previous error + |
