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} ;
2
2
use if_chain:: if_chain;
3
3
use rustc_errors:: Applicability ;
4
4
use rustc_hir:: {
@@ -46,6 +46,9 @@ declare_clippy_lint! {
46
46
/// **Known problems:** If macros are imported through the wildcard, this macro is not included
47
47
/// by the suggestion and has to be added by hand.
48
48
///
49
+ /// Applying the suggestion when explicit imports of the things imported with a glob import
50
+ /// exist, may result in `unused_imports` warnings.
51
+ ///
49
52
/// **Example:**
50
53
///
51
54
/// Bad:
@@ -82,16 +85,27 @@ impl LateLintPass<'_, '_> for WildcardImports {
82
85
if !used_imports. is_empty( ) ; // Already handled by `unused_imports`
83
86
then {
84
87
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( ) {
87
90
// 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.
88
93
(
89
94
use_path. span. with_hi( use_path. span. hi( ) + BytePos ( 1 ) ) ,
90
95
true ,
91
96
)
92
97
} 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
+ }
93
107
(
94
- use_path . span. with_hi ( use_path . span . hi ( ) + BytePos ( 3 ) ) ,
108
+ span,
95
109
false ,
96
110
)
97
111
} ;
@@ -111,10 +125,10 @@ impl LateLintPass<'_, '_> for WildcardImports {
111
125
}
112
126
} ;
113
127
114
- let sugg = if import_source . is_empty ( ) {
128
+ let sugg = if braced_glob {
115
129
imports_string
116
130
} else {
117
- format!( "{}::{}" , import_source , imports_string)
131
+ format!( "{}::{}" , import_source_snippet , imports_string)
118
132
} ;
119
133
120
134
let ( lint, message) = if let Res :: Def ( DefKind :: Enum , _) = use_path. res {
0 commit comments