11use clippy_utils:: diagnostics:: span_lint_and_sugg;
22use clippy_utils:: is_test_module_or_function;
33use clippy_utils:: source:: { snippet, snippet_with_applicability} ;
4+ use rustc_data_structures:: fx:: FxHashSet ;
45use rustc_errors:: Applicability ;
56use rustc_hir:: def:: { DefKind , Res } ;
67use rustc_hir:: { Item , ItemKind , PathSegment , UseKind } ;
@@ -100,13 +101,15 @@ declare_clippy_lint! {
100101pub struct WildcardImports {
101102 warn_on_all : bool ,
102103 test_modules_deep : u32 ,
104+ allowed_segments : FxHashSet < String > ,
103105}
104106
105107impl WildcardImports {
106- pub fn new ( warn_on_all : bool ) -> Self {
108+ pub fn new ( warn_on_all : bool , allowed_wildcard_imports : FxHashSet < String > ) -> Self {
107109 Self {
108110 warn_on_all,
109111 test_modules_deep : 0 ,
112+ allowed_segments : allowed_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_allowed_via_config ( segments, & self . allowed_segments )
193197 }
194198}
195199
@@ -198,10 +202,18 @@ impl WildcardImports {
198202fn 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.
205209fn 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 `allowed-wildcard-imports = ["utils"]` in `Clippy.toml`
215+ fn is_allowed_via_config ( segments : & [ PathSegment < ' _ > ] , allowed_segments : & FxHashSet < String > ) -> bool {
216+ // segment matching need to be exact instead of using 'contains', in case user unintentionaly put
217+ // a single character in the config thus skipping most of the warnings.
218+ segments. iter ( ) . any ( |seg| allowed_segments. contains ( seg. ident . as_str ( ) ) )
219+ }
0 commit comments