@@ -315,6 +315,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
315315 expr_span : Span ,
316316 expr : Option < & ' hir hir:: Expr < ' hir > > ,
317317 pat : Option < & ' hir hir:: Pat < ' hir > > ,
318+ parent_pat : Option < & ' hir hir:: Pat < ' hir > > ,
318319 }
319320 impl < ' hir > Visitor < ' hir > for ExpressionFinder < ' hir > {
320321 fn visit_expr ( & mut self , e : & ' hir hir:: Expr < ' hir > ) {
@@ -327,10 +328,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
327328 if p. span == self . expr_span {
328329 self . pat = Some ( p) ;
329330 }
330- if let hir:: PatKind :: Binding ( hir:: BindingAnnotation :: NONE , _, i, _) = p. kind
331- && i. span == self . expr_span
332- {
333- self . pat = Some ( p) ;
331+ if let hir:: PatKind :: Binding ( hir:: BindingAnnotation :: NONE , _, i, sub) = p. kind {
332+ if i. span == self . expr_span || p. span == self . expr_span {
333+ self . pat = Some ( p) ;
334+ }
335+ // Check if we are in a situation of `ident @ ident` where we want to suggest
336+ // `ref ident @ ref ident` or `ref ident @ Struct { ref ident }`.
337+ if let Some ( subpat) = sub && self . pat . is_none ( ) {
338+ self . visit_pat ( subpat) ;
339+ if self . pat . is_some ( ) {
340+ self . parent_pat = Some ( p) ;
341+ }
342+ return ;
343+ }
334344 }
335345 hir:: intravisit:: walk_pat ( self , p) ;
336346 }
@@ -349,6 +359,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
349359 expr_span : move_span,
350360 expr : None ,
351361 pat : None ,
362+ parent_pat : None ,
352363 } ;
353364 finder. visit_expr ( expr) ;
354365 if let Some ( span) = span && let Some ( expr) = finder. expr {
@@ -414,7 +425,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
414425 span,
415426 format ! (
416427 "consider changing this parameter type in {descr} `{ident}` to \
417- borrow instead if ownering the value isn't necessary",
428+ borrow instead if owning the value isn't necessary",
418429 ) ,
419430 ) ;
420431 }
@@ -434,10 +445,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
434445 }
435446 if let Some ( pat) = finder. pat {
436447 * in_pattern = true ;
437- err. span_suggestion_verbose (
438- pat. span . shrink_to_lo ( ) ,
448+ let mut sugg = vec ! [ ( pat. span. shrink_to_lo( ) , "ref " . to_string( ) ) ] ;
449+ if let Some ( pat) = finder. parent_pat {
450+ sugg. insert ( 0 , ( pat. span . shrink_to_lo ( ) , "ref " . to_string ( ) ) ) ;
451+ }
452+ err. multipart_suggestion_verbose (
439453 "borrow this binding in the pattern to avoid moving the value" ,
440- "ref " . to_string ( ) ,
454+ sugg ,
441455 Applicability :: MachineApplicable ,
442456 ) ;
443457 }
0 commit comments