@@ -99,25 +99,30 @@ 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 parameters = sig. inputs ( ) ;
103-
104- for ( argument, parameter) in iter:: zip ( arguments, parameters) {
105- // we want `argument` to be `Path::new(x)`, which has one arg, x
106- if let ExprKind :: Call ( func, [ arg] ) = argument. kind
107- && is_path_new ( func)
108- && implements_asref_path ( cx. typeck_results ( ) . expr_ty ( arg) )
109- && implements_asref_path ( * parameter)
110- {
111- span_lint_and_sugg (
112- cx,
113- NEEDLESS_PATH_NEW ,
114- argument. span ,
115- "the expression enclosed in `Path::new` implements `AsRef<Path>`" ,
116- "remove the enclosing `Path::new`" ,
117- format ! ( "{}" , snippet( cx, arg. span, ".." ) ) ,
118- Applicability :: MachineApplicable ,
119- ) ;
120- }
121- }
102+ // as far as I understand, `ExprKind::MethodCall` doesn't include the receiver in `args`,
103+ // but does in `sig.inputs()` -- so we iterate over both in `rev`erse in order to line
104+ // them up starting from the _end_
105+ //
106+ // and for `ExprKind::Call` this is basically a no-op
107+ iter:: zip ( sig. inputs ( ) . iter ( ) . rev ( ) , args. iter ( ) . rev ( ) )
108+ . enumerate ( )
109+ . for_each ( |( i, ( arg_ty, arg) ) | {
110+ // we want `argument` to be `Path::new(x)`
111+ if let ExprKind :: Call ( path_new, [ x] ) = arg. kind
112+ && is_path_new ( path_new)
113+ && implements_asref_path ( cx. typeck_results ( ) . expr_ty ( x) )
114+ && implements_asref_path ( * arg_ty)
115+ {
116+ span_lint_and_sugg (
117+ cx,
118+ NEEDLESS_PATH_NEW ,
119+ arg. span ,
120+ "the expression enclosed in `Path::new` implements `AsRef<Path>`" ,
121+ "remove the enclosing `Path::new`" ,
122+ format ! ( "{}" , snippet( cx, x. span, ".." ) ) ,
123+ Applicability :: MachineApplicable ,
124+ ) ;
125+ }
126+ } )
122127 }
123128}
0 commit comments