@@ -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;
@@ -99,6 +99,21 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPathNew<'tcx> {
9999
100100 let implements_asref_path = |arg| implements_trait ( cx, arg, asref_def_id, & [ path_ty. into ( ) ] ) ;
101101
102+ let is_used_anywhere_else = |param_ty : & ParamTy , other_sig_tys : & [ Ty < ' _ > ] | {
103+ other_sig_tys. iter ( ) . any ( |sig_ty| {
104+ sig_ty. walk ( ) . any ( |generic_arg| {
105+ if let Some ( ty) = generic_arg. as_type ( )
106+ && let ty:: Param ( pt) = ty. kind ( )
107+ && pt == param_ty
108+ {
109+ true
110+ } else {
111+ false
112+ }
113+ } )
114+ } )
115+ } ;
116+
102117 // as far as I understand, `ExprKind::MethodCall` doesn't include the receiver in `args`,
103118 // but does in `sig.inputs()` -- so we iterate over both in `rev`erse in order to line
104119 // them up starting from the _end_
@@ -110,7 +125,8 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPathNew<'tcx> {
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 ( arg_param_ty, sig. inputs ( ) )
114130 && implements_asref_path ( * arg_ty)
115131 {
116132 span_lint_and_sugg (
0 commit comments