@@ -1176,6 +1176,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
1176
1176
self . body . source_info ( location) . span
1177
1177
}
1178
1178
} ) ;
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
+
1179
1195
match opt_assignment_rhs_span. and_then ( |s| s. desugaring_kind ( ) ) {
1180
1196
// on for loops, RHS points to the iterator part
1181
1197
Some ( DesugaringKind :: ForLoop ) => {
@@ -1203,6 +1219,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
1203
1219
decl_span,
1204
1220
opt_assignment_rhs_span,
1205
1221
opt_ty_info,
1222
+ rhs_content_source. is_some_and ( |s| {
1223
+ matches ! ( s, BorrowedContentSource :: OverloadedIndex ( _) )
1224
+ } ) ,
1206
1225
)
1207
1226
} else {
1208
1227
match local_decl. local_info ( ) {
@@ -1226,6 +1245,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
1226
1245
decl_span,
1227
1246
opt_assignment_rhs_span,
1228
1247
opt_ty_info,
1248
+ false ,
1229
1249
) ,
1230
1250
}
1231
1251
}
@@ -1507,6 +1527,7 @@ fn suggest_ampmut<'tcx>(
1507
1527
decl_span : Span ,
1508
1528
opt_assignment_rhs_span : Option < Span > ,
1509
1529
opt_ty_info : Option < Span > ,
1530
+ is_overloaded_index : bool ,
1510
1531
) -> Option < AmpMutSugg > {
1511
1532
// if there is a RHS and it starts with a `&` from it, then check if it is
1512
1533
// mutable, and if not, put suggest putting `mut ` to make it mutable.
@@ -1553,6 +1574,28 @@ fn suggest_ampmut<'tcx>(
1553
1574
// if the reference is already mutable then there is nothing we can do
1554
1575
// here.
1555
1576
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
+
1556
1599
// shrink the span to just after the `&` in `&variable`
1557
1600
let span = rhs_span. with_lo ( rhs_span. lo ( ) + BytePos ( 1 ) ) . shrink_to_lo ( ) ;
1558
1601
0 commit comments