@@ -7,7 +7,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
77use rustc_hir:: def_id:: DefId ;
88use rustc_hir:: { Expr , ExprKind , QPath } ;
99use rustc_lint:: { LateContext , LateLintPass } ;
10- use rustc_middle:: ty:: { List , Ty , TyCtxt } ;
10+ use rustc_middle:: ty:: { self , List , ParamTy , Ty , TyCtxt } ;
1111use rustc_session:: impl_lint_pass;
1212use rustc_span:: sym;
1313use std:: iter;
@@ -54,6 +54,21 @@ impl<'tcx> NeedlessPathNew<'tcx> {
5454 }
5555}
5656
57+ fn is_used_anywhere_else < ' a > ( param_ty : & ' _ ParamTy , mut other_sig_tys : impl Iterator < Item = Ty < ' a > > ) -> bool {
58+ other_sig_tys. any ( |sig_ty| {
59+ sig_ty. walk ( ) . any ( |generic_arg| {
60+ if let Some ( ty) = generic_arg. as_type ( )
61+ && let ty:: Param ( pt) = ty. kind ( )
62+ && pt == param_ty
63+ {
64+ true
65+ } else {
66+ false
67+ }
68+ } )
69+ } )
70+ }
71+
5772impl < ' tcx > LateLintPass < ' tcx > for NeedlessPathNew < ' tcx > {
5873 fn check_expr ( & mut self , cx : & LateContext < ' tcx > , e : & ' tcx Expr < ' tcx > ) {
5974 let tcx = cx. tcx ;
@@ -106,11 +121,20 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPathNew<'tcx> {
106121 // and for `ExprKind::Call` this is basically a no-op
107122 iter:: zip ( sig. inputs ( ) . iter ( ) . rev ( ) , args. iter ( ) . rev ( ) )
108123 . enumerate ( )
109- . for_each ( |( i , ( arg_ty, arg) ) | {
124+ . for_each ( |( arg_idx , ( arg_ty, arg) ) | {
110125 // we want `argument` to be `Path::new(x)`
111126 if let ExprKind :: Call ( path_new, [ x] ) = arg. kind
112127 && is_path_new ( path_new)
113- && implements_asref_path ( cx. typeck_results ( ) . expr_ty ( x) )
128+ && let ty:: Param ( arg_param_ty) = arg_ty. kind ( )
129+ && !is_used_anywhere_else (
130+ arg_param_ty,
131+ sig. inputs ( )
132+ . iter ( )
133+ // `arg_idx` is based on the reversed order, so we need to reverse as well
134+ . rev ( )
135+ . enumerate ( )
136+ . filter_map ( |( i, input) | ( i != arg_idx) . then_some ( * input) ) ,
137+ )
114138 && implements_asref_path ( * arg_ty)
115139 {
116140 span_lint_and_sugg (
0 commit comments