Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ad92486

Browse files
committed
Add check for "test" in parent name. Include flag for disabling wildcard import exceptions
1 parent 56f4e1c commit ad92486

File tree

7 files changed

+75
-28
lines changed

7 files changed

+75
-28
lines changed

clippy_lints/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10581058
let max_struct_bools = conf.max_struct_bools;
10591059
store.register_early_pass(move || box excessive_bools::ExcessiveBools::new(max_struct_bools, max_fn_params_bools));
10601060
store.register_early_pass(|| box option_env_unwrap::OptionEnvUnwrap);
1061-
store.register_late_pass(|| box wildcard_imports::WildcardImports);
1061+
let warn_on_all_wildcard_imports = conf.warn_on_all_wildcard_imports;
1062+
store.register_late_pass(move || box wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports));
10621063
store.register_early_pass(|| box macro_use::MacroUseImports);
10631064
store.register_late_pass(|| box verbose_file_reads::VerboseFileReads);
10641065
store.register_late_pass(|| box redundant_pub_crate::RedundantPubCrate::default());

clippy_lints/src/utils/conf.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ define_Conf! {
158158
(max_struct_bools, "max_struct_bools": u64, 3),
159159
/// Lint: FN_PARAMS_EXCESSIVE_BOOLS. The maximum number of bools function parameters can have
160160
(max_fn_params_bools, "max_fn_params_bools": u64, 3),
161+
/// Lint: WILDCARD_IMPORTS. Whether to allow certain wildcard imports (prelude, super in tests).
162+
(warn_on_all_wildcard_imports, "warn_on_all_wildcard_imports": bool, false),
161163
}
162164

163165
impl Default for Conf {

clippy_lints/src/wildcard_imports.rs

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_hir::{
66
Item, ItemKind, PathSegment, UseKind,
77
};
88
use rustc_lint::{LateContext, LateLintPass};
9-
use rustc_session::{declare_lint_pass, declare_tool_lint};
9+
use rustc_session::{declare_tool_lint, impl_lint_pass};
1010
use rustc_span::BytePos;
1111

1212
declare_clippy_lint! {
@@ -73,18 +73,38 @@ declare_clippy_lint! {
7373
"lint `use _::*` statements"
7474
}
7575

76-
declare_lint_pass!(WildcardImports => [ENUM_GLOB_USE, WILDCARD_IMPORTS]);
76+
#[derive(Default)]
77+
pub struct WildcardImports {
78+
warn_on_all: bool,
79+
is_test_module: bool,
80+
test_modules_deep: u32,
81+
}
82+
83+
impl WildcardImports {
84+
pub fn new(warn_on_all: bool) -> Self {
85+
Self {
86+
warn_on_all,
87+
is_test_module: false,
88+
test_modules_deep: 0,
89+
}
90+
}
91+
}
92+
93+
impl_lint_pass!(WildcardImports => [ENUM_GLOB_USE, WILDCARD_IMPORTS]);
7794

7895
impl LateLintPass<'_, '_> for WildcardImports {
7996
fn check_item(&mut self, cx: &LateContext<'_, '_>, item: &Item<'_>) {
8097
if item.vis.node.is_pub() || item.vis.node.is_pub_restricted() {
8198
return;
8299
}
100+
if is_test_module(item) {
101+
self.is_test_module = true;
102+
self.test_modules_deep += 1;
103+
}
83104
if_chain! {
84105
if !in_macro(item.span);
85106
if let ItemKind::Use(use_path, UseKind::Glob) = &item.kind;
86-
if !is_prelude_import(use_path.segments);
87-
if !(is_super_only_import(use_path.segments) && is_in_test_module(cx, item));
107+
if self.warn_on_all || !self.check_exceptions(use_path.segments);
88108
let used_imports = cx.tcx.names_imported_by_glob_use(item.hir_id.owner);
89109
if !used_imports.is_empty(); // Already handled by `unused_imports`
90110
then {
@@ -152,6 +172,19 @@ impl LateLintPass<'_, '_> for WildcardImports {
152172
}
153173
}
154174
}
175+
176+
fn check_item_post(&mut self, _: &LateContext<'_, '_>, _: &Item<'_>) {
177+
if self.is_test_module {
178+
self.is_test_module = false;
179+
self.test_modules_deep -= 1;
180+
}
181+
}
182+
}
183+
184+
impl WildcardImports {
185+
fn check_exceptions(&self, segments: &[PathSegment<'_>]) -> bool {
186+
is_prelude_import(segments) || (is_super_only_import(segments) && self.test_modules_deep > 0)
187+
}
155188
}
156189

157190
// Allow "...prelude::*" imports.
@@ -168,9 +201,6 @@ fn is_super_only_import(segments: &[PathSegment<'_>]) -> bool {
168201
segments.len() == 1 && segments[0].ident.as_str() == "super"
169202
}
170203

171-
fn is_in_test_module(cx: &LateContext<'_, '_>, item: &Item<'_>) -> bool {
172-
let parent = cx.tcx.hir().get_parent_node(item.hir_id);
173-
let parent_item = cx.tcx.hir().expect_item(parent);
174-
let parent_name = parent_item.ident.name.as_str();
175-
parent_name.contains("test")
204+
fn is_test_module(item: &Item<'_>) -> bool {
205+
item.ident.name.as_str().contains("test")
176206
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-struct-bools`, `max-fn-params-bools`, `third-party` at line 5 column 1
1+
error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `third-party` at line 5 column 1
22

33
error: aborting due to previous error
44

tests/ui/wildcard_imports.fixed

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,27 +156,34 @@ fn test_weird_formatting() {
156156
foo();
157157
}
158158

159-
mod test_super_imports {
159+
mod super_imports {
160160
fn foofoo() {}
161161

162-
mod use_super_should_be_replaced {
162+
mod should_be_replaced {
163163
use super::foofoo;
164164

165165
fn with_super() {
166166
let _ = foofoo();
167167
}
168168
}
169169

170-
mod use_super_in_test_should_pass {
170+
mod test_should_pass {
171171
use super::*;
172172

173173
fn with_super() {
174174
let _ = foofoo();
175175
}
176176
}
177177

178+
mod inner {
179+
fn test_should_pass() {
180+
use super::*;
181+
let _ = foofoo();
182+
}
183+
}
184+
178185
mod use_explicit_should_be_replaced {
179-
use test_super_imports::foofoo;
186+
use super_imports::foofoo;
180187

181188
fn with_explicit() {
182189
let _ = foofoo();
@@ -194,7 +201,7 @@ mod test_super_imports {
194201
}
195202

196203
mod use_super_explicit_should_be_replaced {
197-
use super::super::test_super_imports::foofoo;
204+
use super::super::super_imports::foofoo;
198205

199206
fn with_super_explicit() {
200207
let _ = foofoo();

tests/ui/wildcard_imports.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,27 +157,34 @@ fn test_weird_formatting() {
157157
foo();
158158
}
159159

160-
mod test_super_imports {
160+
mod super_imports {
161161
fn foofoo() {}
162162

163-
mod use_super_should_be_replaced {
163+
mod should_be_replaced {
164164
use super::*;
165165

166166
fn with_super() {
167167
let _ = foofoo();
168168
}
169169
}
170170

171-
mod use_super_in_test_should_pass {
171+
mod test_should_pass {
172172
use super::*;
173173

174174
fn with_super() {
175175
let _ = foofoo();
176176
}
177177
}
178178

179+
mod inner {
180+
fn test_should_pass() {
181+
use super::*;
182+
let _ = foofoo();
183+
}
184+
}
185+
179186
mod use_explicit_should_be_replaced {
180-
use test_super_imports::*;
187+
use super_imports::*;
181188

182189
fn with_explicit() {
183190
let _ = foofoo();
@@ -195,7 +202,7 @@ mod test_super_imports {
195202
}
196203

197204
mod use_super_explicit_should_be_replaced {
198-
use super::super::test_super_imports::*;
205+
use super::super::super_imports::*;
199206

200207
fn with_super_explicit() {
201208
let _ = foofoo();

tests/ui/wildcard_imports.stderr

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,22 @@ LL | use super::*;
9999
| ^^^^^^^^ help: try: `super::foofoo`
100100

101101
error: usage of wildcard import
102-
--> $DIR/wildcard_imports.rs:180:13
102+
--> $DIR/wildcard_imports.rs:187:13
103103
|
104-
LL | use test_super_imports::*;
105-
| ^^^^^^^^^^^^^^^^^^^^^ help: try: `test_super_imports::foofoo`
104+
LL | use super_imports::*;
105+
| ^^^^^^^^^^^^^^^^ help: try: `super_imports::foofoo`
106106

107107
error: usage of wildcard import
108-
--> $DIR/wildcard_imports.rs:189:17
108+
--> $DIR/wildcard_imports.rs:196:17
109109
|
110110
LL | use super::super::*;
111111
| ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`
112112

113113
error: usage of wildcard import
114-
--> $DIR/wildcard_imports.rs:198:13
114+
--> $DIR/wildcard_imports.rs:205:13
115115
|
116-
LL | use super::super::test_super_imports::*;
117-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::test_super_imports::foofoo`
116+
LL | use super::super::super_imports::*;
117+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`
118118

119119
error: aborting due to 19 previous errors
120120

0 commit comments

Comments
 (0)