@@ -315,6 +315,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
315
315
expr_span : Span ,
316
316
expr : Option < & ' hir hir:: Expr < ' hir > > ,
317
317
pat : Option < & ' hir hir:: Pat < ' hir > > ,
318
+ parent_pat : Option < & ' hir hir:: Pat < ' hir > > ,
318
319
}
319
320
impl < ' hir > Visitor < ' hir > for ExpressionFinder < ' hir > {
320
321
fn visit_expr ( & mut self , e : & ' hir hir:: Expr < ' hir > ) {
@@ -327,10 +328,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
327
328
if p. span == self . expr_span {
328
329
self . pat = Some ( p) ;
329
330
}
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
+ }
334
344
}
335
345
hir:: intravisit:: walk_pat ( self , p) ;
336
346
}
@@ -349,6 +359,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
349
359
expr_span : move_span,
350
360
expr : None ,
351
361
pat : None ,
362
+ parent_pat : None ,
352
363
} ;
353
364
finder. visit_expr ( expr) ;
354
365
if let Some ( span) = span && let Some ( expr) = finder. expr {
@@ -414,7 +425,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
414
425
span,
415
426
format ! (
416
427
"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",
418
429
) ,
419
430
) ;
420
431
}
@@ -434,10 +445,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
434
445
}
435
446
if let Some ( pat) = finder. pat {
436
447
* 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 (
439
453
"borrow this binding in the pattern to avoid moving the value" ,
440
- "ref " . to_string ( ) ,
454
+ sugg ,
441
455
Applicability :: MachineApplicable ,
442
456
) ;
443
457
}
0 commit comments