3
3
use clippy_utils:: diagnostics:: { span_lint, span_lint_and_sugg, span_lint_and_then} ;
4
4
use clippy_utils:: ptr:: get_spans;
5
5
use clippy_utils:: source:: snippet_opt;
6
- use clippy_utils:: ty:: { is_type_diagnostic_item , match_type , walk_ptrs_hir_ty} ;
6
+ use clippy_utils:: ty:: walk_ptrs_hir_ty;
7
7
use clippy_utils:: { expr_path_res, is_lint_allowed, match_any_diagnostic_items, paths} ;
8
8
use if_chain:: if_chain;
9
9
use rustc_errors:: Applicability ;
10
+ use rustc_hir:: def:: Res ;
10
11
use rustc_hir:: {
11
- BinOpKind , BodyId , Expr , ExprKind , FnDecl , FnRetTy , GenericArg , HirId , Impl , ImplItem , ImplItemKind , Item ,
12
- ItemKind , Lifetime , MutTy , Mutability , Node , PathSegment , QPath , TraitFn , TraitItem , TraitItemKind , Ty , TyKind ,
12
+ BinOpKind , BodyId , Expr , ExprKind , FnDecl , FnRetTy , GenericArg , Impl , ImplItem , ImplItemKind , Item , ItemKind ,
13
+ Lifetime , MutTy , Mutability , Node , PathSegment , QPath , TraitFn , TraitItem , TraitItemKind , Ty , TyKind ,
13
14
} ;
14
15
use rustc_lint:: { LateContext , LateLintPass } ;
15
- use rustc_middle:: ty;
16
16
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
17
17
use rustc_span:: source_map:: Span ;
18
18
use rustc_span:: symbol:: Symbol ;
@@ -153,7 +153,7 @@ declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, INVALID_NULL_PTR_USA
153
153
impl < ' tcx > LateLintPass < ' tcx > for Ptr {
154
154
fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' _ > ) {
155
155
if let ItemKind :: Fn ( ref sig, _, body_id) = item. kind {
156
- check_fn ( cx, sig. decl , item . hir_id ( ) , Some ( body_id) ) ;
156
+ check_fn ( cx, sig. decl , Some ( body_id) ) ;
157
157
}
158
158
}
159
159
@@ -165,7 +165,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
165
165
return ; // ignore trait impls
166
166
}
167
167
}
168
- check_fn ( cx, sig. decl , item . hir_id ( ) , Some ( body_id) ) ;
168
+ check_fn ( cx, sig. decl , Some ( body_id) ) ;
169
169
}
170
170
}
171
171
@@ -176,7 +176,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
176
176
} else {
177
177
None
178
178
} ;
179
- check_fn ( cx, sig. decl , item . hir_id ( ) , body_id) ;
179
+ check_fn ( cx, sig. decl , body_id) ;
180
180
}
181
181
}
182
182
@@ -244,22 +244,31 @@ fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
244
244
}
245
245
246
246
#[ allow( clippy:: too_many_lines) ]
247
- fn check_fn ( cx : & LateContext < ' _ > , decl : & FnDecl < ' _ > , fn_id : HirId , opt_body_id : Option < BodyId > ) {
248
- let fn_def_id = cx. tcx . hir ( ) . local_def_id ( fn_id) ;
249
- let sig = cx. tcx . fn_sig ( fn_def_id) ;
250
- let fn_ty = sig. skip_binder ( ) ;
247
+ fn check_fn ( cx : & LateContext < ' _ > , decl : & FnDecl < ' _ > , opt_body_id : Option < BodyId > ) {
251
248
let body = opt_body_id. map ( |id| cx. tcx . hir ( ) . body ( id) ) ;
252
249
253
- for ( idx, ( arg, ty ) ) in decl. inputs . iter ( ) . zip ( fn_ty . inputs ( ) ) . enumerate ( ) {
250
+ for ( idx, arg) in decl. inputs . iter ( ) . enumerate ( ) {
254
251
// Honor the allow attribute on parameters. See issue 5644.
255
252
if let Some ( body) = & body {
256
253
if is_lint_allowed ( cx, PTR_ARG , body. params [ idx] . hir_id ) {
257
254
continue ;
258
255
}
259
256
}
260
257
261
- if let ty:: Ref ( _, ty, Mutability :: Not ) = ty. kind ( ) {
262
- if is_type_diagnostic_item ( cx, ty, sym:: Vec ) {
258
+ let ( item_name, path) = if_chain ! {
259
+ if let TyKind :: Rptr ( _, MutTy { ty, mutbl: Mutability :: Not } ) = arg. kind;
260
+ if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = ty. kind;
261
+ if let Res :: Def ( _, did) = path. res;
262
+ if let Some ( item_name) = cx. tcx. get_diagnostic_name( did) ;
263
+ then {
264
+ ( item_name, path)
265
+ } else {
266
+ continue
267
+ }
268
+ } ;
269
+
270
+ match item_name {
271
+ sym:: Vec => {
263
272
if let Some ( spans) = get_spans ( cx, opt_body_id, idx, & [ ( "clone" , ".to_owned()" ) ] ) {
264
273
span_lint_and_then (
265
274
cx,
@@ -289,7 +298,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
289
298
} ,
290
299
) ;
291
300
}
292
- } else if is_type_diagnostic_item ( cx, ty, sym:: String ) {
301
+ } ,
302
+ sym:: String => {
293
303
if let Some ( spans) = get_spans ( cx, opt_body_id, idx, & [ ( "clone" , ".to_string()" ) , ( "as_str" , "" ) ] ) {
294
304
span_lint_and_then (
295
305
cx,
@@ -311,7 +321,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
311
321
} ,
312
322
) ;
313
323
}
314
- } else if is_type_diagnostic_item ( cx, ty, sym:: PathBuf ) {
324
+ } ,
325
+ sym:: PathBuf => {
315
326
if let Some ( spans) = get_spans ( cx, opt_body_id, idx, & [ ( "clone" , ".to_path_buf()" ) , ( "as_path" , "" ) ] ) {
316
327
span_lint_and_then (
317
328
cx,
@@ -338,11 +349,10 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
338
349
} ,
339
350
) ;
340
351
}
341
- } else if match_type ( cx, ty, & paths:: COW ) {
352
+ } ,
353
+ sym:: Cow => {
342
354
if_chain ! {
343
- if let TyKind :: Rptr ( _, MutTy { ty, ..} ) = arg. kind;
344
- if let TyKind :: Path ( QPath :: Resolved ( None , pp) ) = ty. kind;
345
- if let [ ref bx] = * pp. segments;
355
+ if let [ ref bx] = * path. segments;
346
356
if let Some ( params) = bx. args;
347
357
if !params. parenthesized;
348
358
if let Some ( inner) = params. args. iter( ) . find_map( |arg| match arg {
@@ -363,7 +373,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
363
373
) ;
364
374
}
365
375
}
366
- }
376
+ } ,
377
+ _ => { } ,
367
378
}
368
379
}
369
380
0 commit comments