@@ -307,7 +307,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
307
307
let local_decl = & self . mir . local_decls [ * local] ;
308
308
let suggestion = match local_decl. is_user_variable . as_ref ( ) . unwrap ( ) {
309
309
ClearCrossCrate :: Set ( mir:: BindingForm :: ImplicitSelf ) => {
310
- Some ( suggest_ampmut_self ( local_decl) )
310
+ Some ( suggest_ampmut_self ( self . tcx , local_decl) )
311
311
}
312
312
313
313
ClearCrossCrate :: Set ( mir:: BindingForm :: Var ( mir:: VarBindingForm {
@@ -418,8 +418,22 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
418
418
}
419
419
}
420
420
421
- fn suggest_ampmut_self < ' cx , ' gcx , ' tcx > ( local_decl : & mir:: LocalDecl < ' tcx > ) -> ( Span , String ) {
422
- ( local_decl. source_info . span , "&mut self" . to_string ( ) )
421
+ fn suggest_ampmut_self < ' cx , ' gcx , ' tcx > (
422
+ tcx : TyCtxt < ' cx , ' gcx , ' tcx > ,
423
+ local_decl : & mir:: LocalDecl < ' tcx > ,
424
+ ) -> ( Span , String ) {
425
+ let sp = local_decl. source_info . span ;
426
+ ( sp, match tcx. sess . codemap ( ) . span_to_snippet ( sp) {
427
+ Ok ( snippet) => {
428
+ let lt_pos = snippet. find ( '\'' ) ;
429
+ if let Some ( lt_pos) = lt_pos {
430
+ format ! ( "&{}mut self" , & snippet[ lt_pos..snippet. len( ) - 4 ] )
431
+ } else {
432
+ "&mut self" . to_string ( )
433
+ }
434
+ }
435
+ _ => "&mut self" . to_string ( )
436
+ } )
423
437
}
424
438
425
439
// When we want to suggest a user change a local variable to be a `&mut`, there
@@ -447,9 +461,15 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>(
447
461
let locations = mir. find_assignments ( local) ;
448
462
if locations. len ( ) > 0 {
449
463
let assignment_rhs_span = mir. source_info ( locations[ 0 ] ) . span ;
450
- let snippet = tcx. sess . codemap ( ) . span_to_snippet ( assignment_rhs_span) ;
451
- if let Ok ( src) = snippet {
452
- if src. starts_with ( '&' ) {
464
+ if let Ok ( src) = tcx. sess . codemap ( ) . span_to_snippet ( assignment_rhs_span) {
465
+ if let ( true , Some ( ws_pos) ) = (
466
+ src. starts_with ( "&'" ) ,
467
+ src. find ( |c : char | -> bool { c. is_whitespace ( ) } ) ,
468
+ ) {
469
+ let lt_name = & src[ 1 ..ws_pos] ;
470
+ let ty = & src[ ws_pos..] ;
471
+ return ( assignment_rhs_span, format ! ( "&{} mut {}" , lt_name, ty) ) ;
472
+ } else if src. starts_with ( '&' ) {
453
473
let borrowed_expr = src[ 1 ..] . to_string ( ) ;
454
474
return ( assignment_rhs_span, format ! ( "&mut {}" , borrowed_expr) ) ;
455
475
}
@@ -466,13 +486,25 @@ fn suggest_ampmut<'cx, 'gcx, 'tcx>(
466
486
None => local_decl. source_info . span ,
467
487
} ;
468
488
489
+ if let Ok ( src) = tcx. sess . codemap ( ) . span_to_snippet ( highlight_span) {
490
+ if let ( true , Some ( ws_pos) ) = (
491
+ src. starts_with ( "&'" ) ,
492
+ src. find ( |c : char | -> bool { c. is_whitespace ( ) } ) ,
493
+ ) {
494
+ let lt_name = & src[ 1 ..ws_pos] ;
495
+ let ty = & src[ ws_pos..] ;
496
+ return ( highlight_span, format ! ( "&{} mut{}" , lt_name, ty) ) ;
497
+ }
498
+ }
499
+
469
500
let ty_mut = local_decl. ty . builtin_deref ( true ) . unwrap ( ) ;
470
501
assert_eq ! ( ty_mut. mutbl, hir:: MutImmutable ) ;
471
- if local_decl. ty . is_region_ptr ( ) {
472
- ( highlight_span, format ! ( "&mut {}" , ty_mut. ty) )
473
- } else {
474
- ( highlight_span, format ! ( "*mut {}" , ty_mut. ty) )
475
- }
502
+ ( highlight_span,
503
+ if local_decl. ty . is_region_ptr ( ) {
504
+ format ! ( "&mut {}" , ty_mut. ty)
505
+ } else {
506
+ format ! ( "*mut {}" , ty_mut. ty)
507
+ } )
476
508
}
477
509
478
510
fn is_closure_or_generator ( ty : ty:: Ty ) -> bool {
0 commit comments