@@ -1176,6 +1176,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
11761176 self . body . source_info ( location) . span
11771177 }
11781178 } ) ;
1179+
1180+ // check if the RHS is an overloaded index expression, if so, suggest using .get_mut() instead of &mut, see issue #143732
1181+ let rhs_content_source = self . find_assignments ( local) . first ( ) . map ( |& location| {
1182+ if let Some ( mir:: Statement {
1183+ source_info : _,
1184+ kind :
1185+ mir:: StatementKind :: Assign ( box ( _, mir:: Rvalue :: Ref ( _, _, place) ) ) ,
1186+ ..
1187+ } ) = self . body [ location. block ] . statements . get ( location. statement_index )
1188+ {
1189+ Some ( self . borrowed_content_source ( place. as_ref ( ) ) )
1190+ } else {
1191+ None
1192+ }
1193+ } ) . flatten ( ) ;
1194+
11791195 match opt_assignment_rhs_span. and_then ( |s| s. desugaring_kind ( ) ) {
11801196 // on for loops, RHS points to the iterator part
11811197 Some ( DesugaringKind :: ForLoop ) => {
@@ -1203,6 +1219,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
12031219 decl_span,
12041220 opt_assignment_rhs_span,
12051221 opt_ty_info,
1222+ rhs_content_source. is_some_and ( |s| {
1223+ matches ! ( s, BorrowedContentSource :: OverloadedIndex ( _) )
1224+ } ) ,
12061225 )
12071226 } else {
12081227 match local_decl. local_info ( ) {
@@ -1226,6 +1245,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
12261245 decl_span,
12271246 opt_assignment_rhs_span,
12281247 opt_ty_info,
1248+ false ,
12291249 ) ,
12301250 }
12311251 }
@@ -1507,6 +1527,7 @@ fn suggest_ampmut<'tcx>(
15071527 decl_span : Span ,
15081528 opt_assignment_rhs_span : Option < Span > ,
15091529 opt_ty_info : Option < Span > ,
1530+ is_overloaded_index : bool ,
15101531) -> Option < AmpMutSugg > {
15111532 // if there is a RHS and it starts with a `&` from it, then check if it is
15121533 // mutable, and if not, put suggest putting `mut ` to make it mutable.
@@ -1553,6 +1574,28 @@ fn suggest_ampmut<'tcx>(
15531574 // if the reference is already mutable then there is nothing we can do
15541575 // here.
15551576 if !is_mut {
1577+ // If this is an overloaded index expression, suggest using .get_mut() instead of &mut
1578+ if is_overloaded_index {
1579+ // Try to extract the expression from &expr[key] to suggest expr.get_mut(key).unwrap()
1580+ let content = rhs_str. strip_prefix ( '&' ) ?;
1581+ if content. contains ( '[' ) && content. contains ( ']' ) {
1582+ let bracket_start = content. find ( '[' ) ?;
1583+ let bracket_end = content. rfind ( ']' ) ?;
1584+
1585+ if bracket_start < bracket_end {
1586+ let map_part = & content[ ..bracket_start] ;
1587+ let key_part = & content[ bracket_start + 1 ..bracket_end] ;
1588+
1589+ return Some ( AmpMutSugg {
1590+ has_sugg : true ,
1591+ span : rhs_span,
1592+ suggestion : format ! ( "{}.get_mut({}).unwrap()" , map_part, key_part) ,
1593+ additional : None ,
1594+ } ) ;
1595+ }
1596+ }
1597+ }
1598+
15561599 // shrink the span to just after the `&` in `&variable`
15571600 let span = rhs_span. with_lo ( rhs_span. lo ( ) + BytePos ( 1 ) ) . shrink_to_lo ( ) ;
15581601
0 commit comments