@@ -50,12 +50,26 @@ pub(super) fn check<'tcx>(
5050 then {
5151 if let hir:: PatKind :: Ref ( ..) = closure_arg. pat. kind {
5252 Some ( search_snippet. replacen( '&' , "" , 1 ) )
53- } else if let PatKind :: Binding ( ..) = strip_pat_refs( closure_arg. pat) . kind {
53+ } else if let PatKind :: Binding ( _, binding_id, _, _) = strip_pat_refs( closure_arg. pat) . kind {
54+ // this binding is composed of at least two levels of references, so we need to remove one
55+ let binding_type = cx. typeck_results( ) . node_type( binding_id) ;
56+ let innermost_is_ref = if let ty:: Ref ( _, inner, _) = binding_type. kind( ) {
57+ matches!( inner. kind( ) , ty:: Ref ( _, innermost, _) if innermost. is_ref( ) )
58+ } else {
59+ false
60+ } ;
61+
5462 // `find()` provides a reference to the item, but `any` does not,
5563 // so we should fix item usages for suggestion
5664 if let Some ( closure_sugg) = get_closure_suggestion( cx, search_arg, closure_body) {
5765 applicability = closure_sugg. applicability;
58- Some ( closure_sugg. suggestion)
66+ if innermost_is_ref {
67+ Some ( closure_sugg. suggestion. replacen( '&' , "" , 1 ) )
68+ } else {
69+ Some ( closure_sugg. suggestion)
70+ }
71+ } else if innermost_is_ref {
72+ Some ( search_snippet. replacen( '&' , "" , 1 ) )
5973 } else {
6074 Some ( search_snippet. to_string( ) )
6175 }
@@ -230,7 +244,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
230244 // cases where a parent call is using the item
231245 // i.e.: suggest `.contains(&x)` for `.find(|x| [1, 2, 3].contains(x)).is_none()`
232246 if let Some ( parent_expr) = get_parent_expr_for_hir ( self . cx , cmt. hir_id ) {
233- if let ExprKind :: Call ( .. ) | ExprKind :: MethodCall ( .. ) = parent_expr. kind {
247+ if let ExprKind :: Call ( _ , call_args ) | ExprKind :: MethodCall ( _ , _ , call_args , _ ) = parent_expr. kind {
234248 let expr = self . cx . tcx . hir ( ) . expect_expr ( cmt. hir_id ) ;
235249 let arg_ty_kind = self . cx . typeck_results ( ) . expr_ty ( expr) . kind ( ) ;
236250
@@ -239,8 +253,13 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
239253 let start_span = Span :: new ( self . next_pos , span. lo ( ) , span. ctxt ( ) ) ;
240254 let start_snip =
241255 snippet_with_applicability ( self . cx , start_span, ".." , & mut self . applicability ) ;
242-
243- self . suggestion_start . push_str ( & format ! ( "{}&{}" , start_snip, ident_str) ) ;
256+ // do not suggest ampersand if the ident is the method caller
257+ let ident_sugg = if !call_args. is_empty ( ) && call_args[ 0 ] . hir_id == cmt. hir_id {
258+ format ! ( "{}{}" , start_snip, ident_str)
259+ } else {
260+ format ! ( "{}&{}" , start_snip, ident_str)
261+ } ;
262+ self . suggestion_start . push_str ( & ident_sugg) ;
244263 self . next_pos = span. hi ( ) ;
245264 } else {
246265 self . applicability = Applicability :: Unspecified ;
0 commit comments