@@ -737,9 +737,9 @@ pub struct DerefClosure {
737737/// such as explicit deref and borrowing cases.
738738/// Returns `None` if no such use cases have been triggered in closure body
739739///
740- /// note: this only works on single line immutable closures
741- pub fn deref_closure_args < ' tcx > ( cx : & LateContext < ' _ > , search_expr : & ' tcx hir:: Expr < ' _ > ) -> Option < DerefClosure > {
742- if let hir:: ExprKind :: Closure ( _, fn_decl, body_id, ..) = search_expr . kind {
740+ /// note: this only works on single line immutable closures with one exactly one input parameter.
741+ pub fn deref_closure_args < ' tcx > ( cx : & LateContext < ' _ > , closure : & ' tcx hir:: Expr < ' _ > ) -> Option < DerefClosure > {
742+ if let hir:: ExprKind :: Closure ( _, fn_decl, body_id, ..) = closure . kind {
743743 let closure_body = cx. tcx . hir ( ) . body ( body_id) ;
744744 // is closure arg a double reference (i.e.: `|x: &&i32| ...`)
745745 let closure_arg_is_double_ref = if let TyKind :: Rptr ( _, MutTy { ty, .. } ) = fn_decl. inputs [ 0 ] . kind {
@@ -750,14 +750,14 @@ pub fn deref_closure_args<'tcx>(cx: &LateContext<'_>, search_expr: &'tcx hir::Ex
750750
751751 let mut visitor = DerefDelegate {
752752 cx,
753- closure_span : search_expr . span ,
753+ closure_span : closure . span ,
754754 closure_arg_is_double_ref,
755- next_pos : search_expr . span . lo ( ) ,
755+ next_pos : closure . span . lo ( ) ,
756756 suggestion_start : String :: new ( ) ,
757757 applicability : Applicability :: MaybeIncorrect ,
758758 } ;
759759
760- let fn_def_id = cx. tcx . hir ( ) . local_def_id ( search_expr . hir_id ) ;
760+ let fn_def_id = cx. tcx . hir ( ) . local_def_id ( closure . hir_id ) ;
761761 cx. tcx . infer_ctxt ( ) . enter ( |infcx| {
762762 ExprUseVisitor :: new ( & mut visitor, & infcx, fn_def_id, cx. param_env , cx. typeck_results ( ) )
763763 . consume_body ( closure_body) ;
@@ -847,7 +847,6 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
847847 if cmt. place . projections . is_empty ( ) {
848848 // handle item without any projection, that needs an explicit borrowing
849849 // i.e.: suggest `&x` instead of `x`
850- self . closure_arg_is_double_ref = false ;
851850 self . suggestion_start . push_str ( & format ! ( "{}&{}" , start_snip, ident_str) ) ;
852851 } else {
853852 // cases where a parent `Call` or `MethodCall` is using the item
@@ -879,21 +878,20 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
879878 let takes_arg_by_double_ref =
880879 self . func_takes_arg_by_double_ref ( parent_expr, cmt. hir_id ) ;
881880
882- // compiler will automatically dereference field projection, so no need
881+ // compiler will automatically dereference field or index projection, so no need
883882 // to suggest ampersand, but full identifier that includes projection is required
884- let has_field_projection = cmt
885- . place
886- . projections
887- . iter ( )
888- . any ( |proj| matches ! ( proj. kind, ProjectionKind :: Field ( ..) ) ) ;
883+ let has_field_or_index_projection =
884+ cmt. place . projections . iter ( ) . any ( |proj| {
885+ matches ! ( proj. kind, ProjectionKind :: Field ( ..) | ProjectionKind :: Index )
886+ } ) ;
889887
890888 // no need to bind again if the function doesn't take arg by double ref
891889 // and if the item is already a double ref
892890 let ident_sugg = if !call_args. is_empty ( )
893891 && !takes_arg_by_double_ref
894- && ( self . closure_arg_is_double_ref || has_field_projection )
892+ && ( self . closure_arg_is_double_ref || has_field_or_index_projection )
895893 {
896- let ident = if has_field_projection {
894+ let ident = if has_field_or_index_projection {
897895 ident_str_with_proj
898896 } else {
899897 ident_str
@@ -953,9 +951,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
953951
954952 // handle `ProjectionKind::Deref` by removing one explicit deref
955953 // if no special case was detected (i.e.: suggest `*x` instead of `**x`)
956- if projections_handled {
957- self . closure_arg_is_double_ref = false ;
958- } else {
954+ if !projections_handled {
959955 let last_deref = cmt
960956 . place
961957 . projections
0 commit comments