1- use crate :: utils:: { in_macro, snippet_with_applicability, span_lint_and_sugg} ;
1+ use crate :: utils:: { in_macro, snippet , snippet_with_applicability, span_lint_and_sugg} ;
22use if_chain:: if_chain;
33use rustc_errors:: Applicability ;
44use rustc_hir:: {
@@ -46,6 +46,9 @@ declare_clippy_lint! {
4646 /// **Known problems:** If macros are imported through the wildcard, this macro is not included
4747 /// by the suggestion and has to be added by hand.
4848 ///
49+ /// Applying the suggestion when explicit imports of the things imported with a glob import
50+ /// exist, may result in `unused_imports` warnings.
51+ ///
4952 /// **Example:**
5053 ///
5154 /// Bad:
@@ -82,16 +85,27 @@ impl LateLintPass<'_, '_> for WildcardImports {
8285 if !used_imports. is_empty( ) ; // Already handled by `unused_imports`
8386 then {
8487 let mut applicability = Applicability :: MachineApplicable ;
85- let import_source = snippet_with_applicability( cx, use_path. span, ".." , & mut applicability) ;
86- let ( span, braced_glob) = if import_source . is_empty( ) {
88+ let import_source_snippet = snippet_with_applicability( cx, use_path. span, ".." , & mut applicability) ;
89+ let ( span, braced_glob) = if import_source_snippet . is_empty( ) {
8790 // This is a `_::{_, *}` import
91+ // In this case `use_path.span` is empty and ends directly in front of the `*`,
92+ // so we need to extend it by one byte.
8893 (
8994 use_path. span. with_hi( use_path. span. hi( ) + BytePos ( 1 ) ) ,
9095 true ,
9196 )
9297 } else {
98+ // In this case, the `use_path.span` ends right before the `::*`, so we need to
99+ // extend it up to the `*`. Since it is hard to find the `*` in weird
100+ // formattings like `use _ :: *;`, we extend it up to, but not including the
101+ // `;`. In nested imports, like `use _::{inner::*, _}` there is no `;` and we
102+ // can just use the end of the item span
103+ let mut span = use_path. span. with_hi( item. span. hi( ) ) ;
104+ if snippet( cx, span, "" ) . ends_with( ';' ) {
105+ span = use_path. span. with_hi( item. span. hi( ) - BytePos ( 1 ) ) ;
106+ }
93107 (
94- use_path . span. with_hi ( use_path . span . hi ( ) + BytePos ( 3 ) ) ,
108+ span,
95109 false ,
96110 )
97111 } ;
@@ -111,10 +125,10 @@ impl LateLintPass<'_, '_> for WildcardImports {
111125 }
112126 } ;
113127
114- let sugg = if import_source . is_empty ( ) {
128+ let sugg = if braced_glob {
115129 imports_string
116130 } else {
117- format!( "{}::{}" , import_source , imports_string)
131+ format!( "{}::{}" , import_source_snippet , imports_string)
118132 } ;
119133
120134 let ( lint, message) = if let Res :: Def ( DefKind :: Enum , _) = use_path. res {
0 commit comments