33use clippy_utils:: diagnostics:: { span_lint, span_lint_and_sugg, span_lint_and_then} ;
44use clippy_utils:: ptr:: get_spans;
55use 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;
77use clippy_utils:: { expr_path_res, is_lint_allowed, match_any_diagnostic_items, paths} ;
88use if_chain:: if_chain;
99use rustc_errors:: Applicability ;
10+ use rustc_hir:: def:: Res ;
1011use 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 ,
1314} ;
1415use rustc_lint:: { LateContext , LateLintPass } ;
15- use rustc_middle:: ty;
1616use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
1717use rustc_span:: source_map:: Span ;
1818use rustc_span:: symbol:: Symbol ;
@@ -153,7 +153,7 @@ declare_lint_pass!(Ptr => [PTR_ARG, CMP_NULL, MUT_FROM_REF, INVALID_NULL_PTR_USA
153153impl < ' tcx > LateLintPass < ' tcx > for Ptr {
154154 fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx Item < ' _ > ) {
155155 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) ) ;
157157 }
158158 }
159159
@@ -165,7 +165,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
165165 return ; // ignore trait impls
166166 }
167167 }
168- check_fn ( cx, sig. decl , item . hir_id ( ) , Some ( body_id) ) ;
168+ check_fn ( cx, sig. decl , Some ( body_id) ) ;
169169 }
170170 }
171171
@@ -176,7 +176,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
176176 } else {
177177 None
178178 } ;
179- check_fn ( cx, sig. decl , item . hir_id ( ) , body_id) ;
179+ check_fn ( cx, sig. decl , body_id) ;
180180 }
181181 }
182182
@@ -244,22 +244,31 @@ fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
244244}
245245
246246#[ 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 > ) {
251248 let body = opt_body_id. map ( |id| cx. tcx . hir ( ) . body ( id) ) ;
252249
253- for ( idx, ( arg, ty ) ) in decl. inputs . iter ( ) . zip ( fn_ty . inputs ( ) ) . enumerate ( ) {
250+ for ( idx, arg) in decl. inputs . iter ( ) . enumerate ( ) {
254251 // Honor the allow attribute on parameters. See issue 5644.
255252 if let Some ( body) = & body {
256253 if is_lint_allowed ( cx, PTR_ARG , body. params [ idx] . hir_id ) {
257254 continue ;
258255 }
259256 }
260257
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 => {
263272 if let Some ( spans) = get_spans ( cx, opt_body_id, idx, & [ ( "clone" , ".to_owned()" ) ] ) {
264273 span_lint_and_then (
265274 cx,
@@ -289,7 +298,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
289298 } ,
290299 ) ;
291300 }
292- } else if is_type_diagnostic_item ( cx, ty, sym:: String ) {
301+ } ,
302+ sym:: String => {
293303 if let Some ( spans) = get_spans ( cx, opt_body_id, idx, & [ ( "clone" , ".to_string()" ) , ( "as_str" , "" ) ] ) {
294304 span_lint_and_then (
295305 cx,
@@ -311,7 +321,8 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
311321 } ,
312322 ) ;
313323 }
314- } else if is_type_diagnostic_item ( cx, ty, sym:: PathBuf ) {
324+ } ,
325+ sym:: PathBuf => {
315326 if let Some ( spans) = get_spans ( cx, opt_body_id, idx, & [ ( "clone" , ".to_path_buf()" ) , ( "as_path" , "" ) ] ) {
316327 span_lint_and_then (
317328 cx,
@@ -338,11 +349,10 @@ fn check_fn(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_id: HirId, opt_body_id:
338349 } ,
339350 ) ;
340351 }
341- } else if match_type ( cx, ty, & paths:: COW ) {
352+ } ,
353+ sym:: Cow => {
342354 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;
346356 if let Some ( params) = bx. args;
347357 if !params. parenthesized;
348358 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:
363373 ) ;
364374 }
365375 }
366- }
376+ } ,
377+ _ => { } ,
367378 }
368379 }
369380
0 commit comments