@@ -1100,12 +1100,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11001100 }
11011101 let decl_span = local_decl. source_info . span ;
11021102
1103- let label = match * local_decl. local_info ( ) {
1103+ let amp_mut_sugg = match * local_decl. local_info ( ) {
11041104 LocalInfo :: User ( mir:: BindingForm :: ImplicitSelf ( _) ) => {
11051105 let suggestion = suggest_ampmut_self ( self . infcx . tcx , decl_span) ;
11061106 let additional =
11071107 local_trait. map ( |span| ( span, suggest_ampmut_self ( self . infcx . tcx , span) ) ) ;
1108- Some ( ( true , decl_span, suggestion, additional) )
1108+ Some ( AmpMutSugg { has_sugg : true , span : decl_span, suggestion, additional } )
11091109 }
11101110
11111111 LocalInfo :: User ( mir:: BindingForm :: Var ( mir:: VarBindingForm {
@@ -1150,7 +1150,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11501150 None
11511151 }
11521152 None => {
1153- let ( has_sugg , decl_span , sugg ) = if name != kw:: SelfLower {
1153+ if name != kw:: SelfLower {
11541154 suggest_ampmut (
11551155 self . infcx . tcx ,
11561156 local_decl. ty ,
@@ -1165,7 +1165,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11651165 ..
11661166 } ) ) => {
11671167 let sugg = suggest_ampmut_self ( self . infcx . tcx , decl_span) ;
1168- ( true , decl_span, sugg)
1168+ Some ( AmpMutSugg {
1169+ has_sugg : true ,
1170+ span : decl_span,
1171+ suggestion : sugg,
1172+ additional : None ,
1173+ } )
11691174 }
11701175 // explicit self (eg `self: &'a Self`)
11711176 _ => suggest_ampmut (
@@ -1176,8 +1181,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11761181 opt_ty_info,
11771182 ) ,
11781183 }
1179- } ;
1180- Some ( ( has_sugg, decl_span, sugg, None ) )
1184+ }
11811185 }
11821186 }
11831187 }
@@ -1187,15 +1191,24 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11871191 ..
11881192 } ) ) => {
11891193 let pattern_span: Span = local_decl. source_info . span ;
1190- suggest_ref_mut ( self . infcx . tcx , pattern_span)
1191- . map ( |span| ( true , span, "mut " . to_owned ( ) , None ) )
1194+ suggest_ref_mut ( self . infcx . tcx , pattern_span) . map ( |span| AmpMutSugg {
1195+ has_sugg : true ,
1196+ span,
1197+ suggestion : "mut " . to_owned ( ) ,
1198+ additional : None ,
1199+ } )
11921200 }
11931201
11941202 _ => unreachable ! ( ) ,
11951203 } ;
11961204
1197- match label {
1198- Some ( ( true , err_help_span, suggested_code, additional) ) => {
1205+ match amp_mut_sugg {
1206+ Some ( AmpMutSugg {
1207+ has_sugg : true ,
1208+ span : err_help_span,
1209+ suggestion : suggested_code,
1210+ additional,
1211+ } ) => {
11991212 let mut sugg = vec ! [ ( err_help_span, suggested_code) ] ;
12001213 if let Some ( s) = additional {
12011214 sugg. push ( s) ;
@@ -1217,7 +1230,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
12171230 ) ;
12181231 }
12191232 }
1220- Some ( ( false , err_label_span, message, _) ) => {
1233+ Some ( AmpMutSugg {
1234+ has_sugg : false , span : err_label_span, suggestion : message, ..
1235+ } ) => {
12211236 let def_id = self . body . source . def_id ( ) ;
12221237 let hir_id = if let Some ( local_def_id) = def_id. as_local ( )
12231238 && let Some ( body) = self . infcx . tcx . hir ( ) . maybe_body_owned_by ( local_def_id)
@@ -1422,6 +1437,13 @@ fn suggest_ampmut_self<'tcx>(tcx: TyCtxt<'tcx>, span: Span) -> String {
14221437 }
14231438}
14241439
1440+ struct AmpMutSugg {
1441+ has_sugg : bool ,
1442+ span : Span ,
1443+ suggestion : String ,
1444+ additional : Option < ( Span , String ) > ,
1445+ }
1446+
14251447// When we want to suggest a user change a local variable to be a `&mut`, there
14261448// are three potential "obvious" things to highlight:
14271449//
@@ -1443,7 +1465,7 @@ fn suggest_ampmut<'tcx>(
14431465 decl_span : Span ,
14441466 opt_assignment_rhs_span : Option < Span > ,
14451467 opt_ty_info : Option < Span > ,
1446- ) -> ( bool , Span , String ) {
1468+ ) -> Option < AmpMutSugg > {
14471469 // if there is a RHS and it starts with a `&` from it, then check if it is
14481470 // mutable, and if not, put suggest putting `mut ` to make it mutable.
14491471 // we don't have to worry about lifetime annotations here because they are
@@ -1456,6 +1478,11 @@ fn suggest_ampmut<'tcx>(
14561478 && let Ok ( src) = tcx. sess . source_map ( ) . span_to_snippet ( assignment_rhs_span)
14571479 && let Some ( stripped) = src. strip_prefix ( '&' )
14581480 {
1481+ let is_raw_ref = stripped. trim_start ( ) . starts_with ( "raw " ) ;
1482+ // We don't support raw refs yet
1483+ if is_raw_ref {
1484+ return None ;
1485+ }
14591486 let is_mut = if let Some ( rest) = stripped. trim_start ( ) . strip_prefix ( "mut" ) {
14601487 match rest. chars ( ) . next ( ) {
14611488 // e.g. `&mut x`
@@ -1479,7 +1506,12 @@ fn suggest_ampmut<'tcx>(
14791506
14801507 // FIXME(Ezrashaw): returning is bad because we still might want to
14811508 // update the annotated type, see #106857.
1482- return ( true , span, "mut " . to_owned ( ) ) ;
1509+ return Some ( AmpMutSugg {
1510+ has_sugg : true ,
1511+ span,
1512+ suggestion : "mut " . to_owned ( ) ,
1513+ additional : None ,
1514+ } ) ;
14831515 }
14841516 }
14851517
@@ -1504,18 +1536,23 @@ fn suggest_ampmut<'tcx>(
15041536 && let Some ( ws_pos) = src. find ( char:: is_whitespace)
15051537 {
15061538 let span = span. with_lo ( span. lo ( ) + BytePos ( ws_pos as u32 ) ) . shrink_to_lo ( ) ;
1507- ( true , span, " mut" . to_owned ( ) )
1539+ Some ( AmpMutSugg { has_sugg : true , span, suggestion : " mut" . to_owned ( ) , additional : None } )
15081540 // if there is already a binding, we modify it to be `mut`
15091541 } else if binding_exists {
15101542 // shrink the span to just after the `&` in `&variable`
15111543 let span = span. with_lo ( span. lo ( ) + BytePos ( 1 ) ) . shrink_to_lo ( ) ;
1512- ( true , span, "mut " . to_owned ( ) )
1544+ Some ( AmpMutSugg { has_sugg : true , span, suggestion : "mut " . to_owned ( ) , additional : None } )
15131545 } else {
15141546 // otherwise, suggest that the user annotates the binding; we provide the
15151547 // type of the local.
15161548 let ty = decl_ty. builtin_deref ( true ) . unwrap ( ) ;
15171549
1518- ( false , span, format ! ( "{}mut {}" , if decl_ty. is_ref( ) { "&" } else { "*" } , ty) )
1550+ Some ( AmpMutSugg {
1551+ has_sugg : false ,
1552+ span,
1553+ suggestion : format ! ( "{}mut {}" , if decl_ty. is_ref( ) { "&" } else { "*" } , ty) ,
1554+ additional : None ,
1555+ } )
15191556 }
15201557}
15211558
0 commit comments