1- use clippy_utils:: diagnostics:: span_lint_and_sugg;
1+ use clippy_utils:: diagnostics:: { span_lint_and_help , span_lint_and_sugg} ;
22use clippy_utils:: in_macro;
33use rustc_ast:: { ptr:: P , Crate , Item , ItemKind , ModKind , UseTreeKind } ;
44use rustc_errors:: Applicability ;
@@ -66,15 +66,27 @@ fn check_mod(cx: &EarlyContext<'_>, items: &[P<Item>]) {
6666
6767 for single_use in & single_use_usages {
6868 if !imports_reused_with_self. contains ( & single_use. 0 ) {
69- span_lint_and_sugg (
70- cx,
71- SINGLE_COMPONENT_PATH_IMPORTS ,
72- single_use. 1 ,
73- "this import is redundant" ,
74- "remove it entirely" ,
75- String :: new ( ) ,
76- Applicability :: MachineApplicable ,
77- ) ;
69+ let can_suggest = single_use. 2 ;
70+ if can_suggest {
71+ span_lint_and_sugg (
72+ cx,
73+ SINGLE_COMPONENT_PATH_IMPORTS ,
74+ single_use. 1 ,
75+ "this import is redundant" ,
76+ "remove it entirely" ,
77+ String :: new ( ) ,
78+ Applicability :: MachineApplicable ,
79+ ) ;
80+ } else {
81+ span_lint_and_help (
82+ cx,
83+ SINGLE_COMPONENT_PATH_IMPORTS ,
84+ single_use. 1 ,
85+ "this import is redundant" ,
86+ None ,
87+ "remove this import" ,
88+ ) ;
89+ }
7890 }
7991 }
8092}
@@ -83,7 +95,7 @@ fn track_uses(
8395 cx : & EarlyContext < ' _ > ,
8496 item : & Item ,
8597 imports_reused_with_self : & mut Vec < Symbol > ,
86- single_use_usages : & mut Vec < ( Symbol , Span ) > ,
98+ single_use_usages : & mut Vec < ( Symbol , Span , bool ) > ,
8799) {
88100 if in_macro ( item. span ) || item. vis . kind . is_pub ( ) {
89101 return ;
@@ -100,25 +112,40 @@ fn track_uses(
100112 if segments. len ( ) == 1 {
101113 if let UseTreeKind :: Simple ( None , _, _) = use_tree. kind {
102114 let ident = & segments[ 0 ] . ident ;
103- single_use_usages. push ( ( ident. name , item. span ) ) ;
115+ single_use_usages. push ( ( ident. name , item. span , true ) ) ;
104116 }
105117 return ;
106118 }
107119
108- // keep track of `use self::some_module` usages
109- if segments[ 0 ] . ident . name == kw:: SelfLower {
110- // simple case such as `use self::module::SomeStruct`
111- if segments. len ( ) > 1 {
112- imports_reused_with_self. push ( segments[ 1 ] . ident . name ) ;
113- return ;
114- }
115-
116- // nested case such as `use self::{module1::Struct1, module2::Struct2}`
120+ if segments. is_empty ( ) {
121+ // keep track of `use {some_module, some_other_module};` usages
117122 if let UseTreeKind :: Nested ( trees) = & use_tree. kind {
118123 for tree in trees {
119124 let segments = & tree. 0 . prefix . segments ;
120- if !segments. is_empty ( ) {
121- imports_reused_with_self. push ( segments[ 0 ] . ident . name ) ;
125+ if segments. len ( ) == 1 {
126+ if let UseTreeKind :: Simple ( None , _, _) = tree. 0 . kind {
127+ let ident = & segments[ 0 ] . ident ;
128+ single_use_usages. push ( ( ident. name , tree. 0 . span , false ) ) ;
129+ }
130+ }
131+ }
132+ }
133+ } else {
134+ // keep track of `use self::some_module` usages
135+ if segments[ 0 ] . ident . name == kw:: SelfLower {
136+ // simple case such as `use self::module::SomeStruct`
137+ if segments. len ( ) > 1 {
138+ imports_reused_with_self. push ( segments[ 1 ] . ident . name ) ;
139+ return ;
140+ }
141+
142+ // nested case such as `use self::{module1::Struct1, module2::Struct2}`
143+ if let UseTreeKind :: Nested ( trees) = & use_tree. kind {
144+ for tree in trees {
145+ let segments = & tree. 0 . prefix . segments ;
146+ if !segments. is_empty ( ) {
147+ imports_reused_with_self. push ( segments[ 0 ] . ident . name ) ;
148+ }
122149 }
123150 }
124151 }
0 commit comments