@@ -227,23 +227,23 @@ impl DerefDelegate<'_, 'tcx> {
227227 }
228228
229229 fn func_takes_arg_by_ref ( & self , parent_expr : & ' tcx hir:: Expr < ' _ > , cmt_hir_id : HirId ) -> bool {
230- if_chain ! {
231- if let ExprKind :: Call ( func, call_args) = parent_expr. kind;
232- let typ = self . cx. typeck_results( ) . expr_ty( func) ;
233- if let ty:: FnDef ( ..) = typ. kind( ) ;
234-
235- then {
236- let mut takes_by_ref = false ;
237- for ( arg, ty) in iter:: zip( call_args, typ. fn_sig( self . cx. tcx) . skip_binder( ) . inputs( ) ) {
238- if arg. hir_id == cmt_hir_id {
239- takes_by_ref = matches!( ty. kind( ) , ty:: Ref ( _, inner, _) if inner. is_ref( ) ) ;
240- }
230+ let ( call_args, inputs) = match parent_expr. kind {
231+ ExprKind :: MethodCall ( _, _, call_args, _) => {
232+ if let Some ( method_did) = self . cx . typeck_results ( ) . type_dependent_def_id ( parent_expr. hir_id ) {
233+ ( call_args, self . cx . tcx . fn_sig ( method_did) . skip_binder ( ) . inputs ( ) )
234+ } else {
235+ return false ;
241236 }
242- takes_by_ref
243- } else {
244- false
245- }
246- }
237+ } ,
238+ ExprKind :: Call ( func, call_args) => {
239+ let typ = self . cx . typeck_results ( ) . expr_ty ( func) ;
240+ ( call_args, typ. fn_sig ( self . cx . tcx ) . skip_binder ( ) . inputs ( ) )
241+ } ,
242+ _ => return false ,
243+ } ;
244+
245+ iter:: zip ( call_args, inputs)
246+ . any ( |( arg, ty) | arg. hir_id == cmt_hir_id && matches ! ( ty. kind( ) , ty:: Ref ( _, inner, _) if inner. is_ref( ) ) )
247247 }
248248}
249249
@@ -271,10 +271,6 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
271271 let arg_ty_kind = self . cx . typeck_results ( ) . expr_ty ( expr) . kind ( ) ;
272272
273273 if matches ! ( arg_ty_kind, ty:: Ref ( _, _, Mutability :: Not ) ) {
274- let start_span = Span :: new ( self . next_pos , span. lo ( ) , span. ctxt ( ) ) ;
275- let start_snip =
276- snippet_with_applicability ( self . cx , start_span, ".." , & mut self . applicability ) ;
277-
278274 // suggest ampersand if call function is taking args by ref
279275 let takes_arg_by_ref = self . func_takes_arg_by_ref ( parent_expr, cmt. hir_id ) ;
280276
@@ -294,14 +290,12 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
294290 }
295291 }
296292
297- // handle item projections by removing one explicit deref
298- // i.e.: suggest `*x` instead of `**x`
299293 let mut replacement_str = ident_str;
300-
301294 let mut projections_handled = false ;
302295 cmt. place . projections . iter ( ) . enumerate ( ) . for_each ( |( i, proj) | {
303296 match proj. kind {
304297 // Field projection like `|v| v.foo`
298+ // no adjustment needed here, as field projections are handled by the compiler
305299 ProjectionKind :: Field ( idx, variant) => match cmt. place . ty_before_projection ( i) . kind ( ) {
306300 ty:: Adt ( def, ..) => {
307301 replacement_str = format ! (
@@ -342,7 +336,8 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
342336 }
343337 } ) ;
344338
345- // handle `ProjectionKind::Deref` if no special case detected
339+ // handle `ProjectionKind::Deref` by removing one explicit deref
340+ // if no special case was detected (i.e.: suggest `*x` instead of `**x`)
346341 if !projections_handled {
347342 let last_deref = cmt
348343 . place
0 commit comments