@@ -563,11 +563,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
563
563
} = move_spans
564
564
&& can_suggest_clone
565
565
{
566
- self . suggest_cloning ( err, ty, expr, None , Some ( move_spans) ) ;
566
+ self . suggest_cloning ( err, ty, expr, Some ( move_spans) ) ;
567
567
} else if self . suggest_hoisting_call_outside_loop ( err, expr) && can_suggest_clone {
568
568
// The place where the type moves would be misleading to suggest clone.
569
569
// #121466
570
- self . suggest_cloning ( err, ty, expr, None , Some ( move_spans) ) ;
570
+ self . suggest_cloning ( err, ty, expr, Some ( move_spans) ) ;
571
571
}
572
572
}
573
573
@@ -1229,8 +1229,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
1229
1229
& self ,
1230
1230
err : & mut Diag < ' _ > ,
1231
1231
ty : Ty < ' tcx > ,
1232
- mut expr : & ' tcx hir:: Expr < ' tcx > ,
1233
- mut other_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
1232
+ expr : & ' tcx hir:: Expr < ' tcx > ,
1234
1233
use_spans : Option < UseSpans < ' tcx > > ,
1235
1234
) {
1236
1235
if let hir:: ExprKind :: Struct ( _, _, Some ( _) ) = expr. kind {
@@ -1242,66 +1241,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
1242
1241
return ;
1243
1242
}
1244
1243
1245
- if let Some ( some_other_expr) = other_expr
1246
- && let Some ( parent_binop) =
1247
- self . infcx . tcx . hir ( ) . parent_iter ( expr. hir_id ) . find_map ( |n| {
1248
- if let ( hir_id, hir:: Node :: Expr ( e) ) = n
1249
- && let hir:: ExprKind :: AssignOp ( _binop, target, _arg) = e. kind
1250
- && target. hir_id == expr. hir_id
1251
- {
1252
- Some ( hir_id)
1253
- } else {
1254
- None
1255
- }
1256
- } )
1257
- && let Some ( other_parent_binop) =
1258
- self . infcx . tcx . hir ( ) . parent_iter ( some_other_expr. hir_id ) . find_map ( |n| {
1259
- if let ( hir_id, hir:: Node :: Expr ( expr) ) = n
1260
- && let hir:: ExprKind :: AssignOp ( ..) = expr. kind
1261
- {
1262
- Some ( hir_id)
1263
- } else {
1264
- None
1265
- }
1266
- } )
1267
- && parent_binop == other_parent_binop
1268
- {
1269
- // Explicitly look for `expr += other_expr;` and avoid suggesting
1270
- // `expr.clone() += other_expr;`, instead suggesting `expr += other_expr.clone();`.
1271
- other_expr = Some ( expr) ;
1272
- expr = some_other_expr;
1273
- }
1274
- ' outer: {
1275
- if let ty:: Ref ( ..) = ty. kind ( ) {
1276
- // We check for either `let binding = foo(expr, other_expr);` or
1277
- // `foo(expr, other_expr);` and if so we don't suggest an incorrect
1278
- // `foo(expr, other_expr).clone()`
1279
- if let Some ( other_expr) = other_expr
1280
- && let Some ( parent_let) =
1281
- self . infcx . tcx . hir ( ) . parent_iter ( expr. hir_id ) . find_map ( |n| {
1282
- if let ( hir_id, hir:: Node :: LetStmt ( _) | hir:: Node :: Stmt ( _) ) = n {
1283
- Some ( hir_id)
1284
- } else {
1285
- None
1286
- }
1287
- } )
1288
- && let Some ( other_parent_let) =
1289
- self . infcx . tcx . hir ( ) . parent_iter ( other_expr. hir_id ) . find_map ( |n| {
1290
- if let ( hir_id, hir:: Node :: LetStmt ( _) | hir:: Node :: Stmt ( _) ) = n {
1291
- Some ( hir_id)
1292
- } else {
1293
- None
1294
- }
1295
- } )
1296
- && parent_let == other_parent_let
1297
- {
1298
- // Explicitly check that we don't have `foo(&*expr, other_expr)`, as cloning the
1299
- // result of `foo(...)` won't help.
1300
- break ' outer;
1301
- }
1302
- }
1303
- }
1304
- let ty = ty. peel_refs ( ) ;
1305
1244
if self . implements_clone ( ty) {
1306
1245
self . suggest_cloning_inner ( err, ty, expr) ;
1307
1246
} else if let ty:: Adt ( def, args) = ty. kind ( )
@@ -1573,10 +1512,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
1573
1512
) ;
1574
1513
self . suggest_copy_for_type_in_cloned_ref ( & mut err, place) ;
1575
1514
let typeck_results = self . infcx . tcx . typeck ( self . mir_def_id ( ) ) ;
1576
- if let Some ( expr) = self . find_expr ( borrow_span)
1577
- && let Some ( ty) = typeck_results. node_type_opt ( expr. hir_id )
1578
- {
1579
- self . suggest_cloning ( & mut err, ty, expr, self . find_expr ( span) , Some ( move_spans) ) ;
1515
+ if let Some ( expr) = self . find_expr ( borrow_span) {
1516
+ // This is a borrow span, so we want to suggest cloning the referent.
1517
+ if let hir:: ExprKind :: AddrOf ( _, _, borrowed_expr) = expr. kind
1518
+ && let Some ( ty) = typeck_results. expr_ty_opt ( borrowed_expr)
1519
+ {
1520
+ self . suggest_cloning ( & mut err, ty, borrowed_expr, Some ( move_spans) ) ;
1521
+ } else if typeck_results. expr_adjustments ( expr) . first ( ) . is_some_and ( |adj| {
1522
+ matches ! (
1523
+ adj. kind,
1524
+ ty:: adjustment:: Adjust :: Borrow ( ty:: adjustment:: AutoBorrow :: Ref (
1525
+ _,
1526
+ ty:: adjustment:: AutoBorrowMutability :: Not
1527
+ | ty:: adjustment:: AutoBorrowMutability :: Mut {
1528
+ allow_two_phase_borrow: ty:: adjustment:: AllowTwoPhase :: No
1529
+ }
1530
+ ) )
1531
+ )
1532
+ } ) && let Some ( ty) = typeck_results. expr_ty_opt ( expr)
1533
+ {
1534
+ self . suggest_cloning ( & mut err, ty, expr, Some ( move_spans) ) ;
1535
+ }
1580
1536
}
1581
1537
self . buffer_error ( err) ;
1582
1538
}
0 commit comments