@@ -16,7 +16,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint};
16
16
use rustc_span:: { BytePos , Span } ;
17
17
use rustc_typeck:: hir_ty_to_ty;
18
18
19
- use crate :: utils:: { differing_macro_contexts , span_lint_and_sugg} ;
19
+ use crate :: utils:: span_lint_and_sugg;
20
20
21
21
declare_clippy_lint ! {
22
22
/// **What it does:** Checks for unnecessary repetition of structure name when a
@@ -79,6 +79,19 @@ fn span_lint_ignore_last_segment<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, path: &'t
79
79
}
80
80
}
81
81
82
+ fn span_lint_on_qpath_resolved < ' a , ' tcx > ( cx : & LateContext < ' a , ' tcx > , qpath : & ' tcx QPath < ' tcx > , enum_variant : bool ) {
83
+ match qpath {
84
+ QPath :: Resolved ( _, path) => {
85
+ if enum_variant {
86
+ span_lint_ignore_last_segment ( cx, path) ;
87
+ } else {
88
+ span_lint ( cx, path. span ) ;
89
+ }
90
+ } ,
91
+ _ => ( ) ,
92
+ } ;
93
+ }
94
+
82
95
struct ImplVisitor < ' a , ' tcx > {
83
96
cx : & ' a LateContext < ' a , ' tcx > ,
84
97
item : & ' tcx Item < ' tcx > ,
@@ -185,29 +198,34 @@ impl<'a, 'tcx> Visitor<'tcx> for ImplVisitor<'a, 'tcx> {
185
198
}
186
199
}
187
200
} ,
201
+ // type-relative fn calls (`Foo::new()`) and tuple-like instantiation (`Foo(arg)` or `Enum::Foo(arg)`)
188
202
ExprKind :: Call (
189
- Expr {
190
- kind :
191
- ExprKind :: Path ( QPath :: Resolved (
192
- _,
193
- path
194
- @
195
- Path {
196
- res : def:: Res :: Def ( def:: DefKind :: Ctor ( ctor_of, _) , _) ,
197
- ..
198
- } ,
199
- ) ) ,
203
+ fun
204
+ @ Expr {
205
+ kind : ExprKind :: Path ( ref qpath) ,
200
206
..
201
207
} ,
202
208
_,
203
209
) => {
204
210
if expr_ty_matches ( expr, self . self_ty , self . cx ) {
205
- match ctor_of {
206
- def:: CtorOf :: Struct => span_lint ( self . cx , path. span ) ,
207
- def:: CtorOf :: Variant => span_lint_ignore_last_segment ( self . cx , path) ,
211
+ let res = self . cx . tables . qpath_res ( qpath, fun. hir_id ) ;
212
+
213
+ if let def:: Res :: Def ( DefKind :: Ctor ( ctor_of, _) , ..) = res {
214
+ match ctor_of {
215
+ def:: CtorOf :: Variant => span_lint_on_qpath_resolved ( self . cx , qpath, true ) ,
216
+ def:: CtorOf :: Struct => span_lint_on_qpath_resolved ( self . cx , qpath, false ) ,
217
+ }
218
+ } else if let def:: Res :: Def ( DefKind :: Variant , ..) = res {
219
+ span_lint_on_qpath_resolved ( self . cx , qpath, true ) ;
208
220
}
209
221
}
210
222
} ,
223
+ // unit enum variants (`Enum::A`)
224
+ ExprKind :: Path ( ref qpath) => {
225
+ if expr_ty_matches ( expr, self . self_ty , self . cx ) {
226
+ span_lint_on_qpath_resolved ( self . cx , qpath, true ) ;
227
+ }
228
+ } ,
211
229
_ => ( ) ,
212
230
}
213
231
walk_expr ( self , expr) ;
0 commit comments