@@ -570,11 +570,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
570570 } = move_spans
571571 && can_suggest_clone
572572 {
573- self . suggest_cloning ( err, ty, expr, None , Some ( move_spans) ) ;
573+ self . suggest_cloning ( err, ty, expr, Some ( move_spans) ) ;
574574 } else if self . suggest_hoisting_call_outside_loop ( err, expr) && can_suggest_clone {
575575 // The place where the type moves would be misleading to suggest clone.
576576 // #121466
577- self . suggest_cloning ( err, ty, expr, None , Some ( move_spans) ) ;
577+ self . suggest_cloning ( err, ty, expr, Some ( move_spans) ) ;
578578 }
579579 }
580580
@@ -1236,8 +1236,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
12361236 & self ,
12371237 err : & mut Diag < ' _ > ,
12381238 ty : Ty < ' tcx > ,
1239- mut expr : & ' tcx hir:: Expr < ' tcx > ,
1240- mut other_expr : Option < & ' tcx hir:: Expr < ' tcx > > ,
1239+ expr : & ' tcx hir:: Expr < ' tcx > ,
12411240 use_spans : Option < UseSpans < ' tcx > > ,
12421241 ) {
12431242 if let hir:: ExprKind :: Struct ( _, _, Some ( _) ) = expr. kind {
@@ -1249,66 +1248,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
12491248 return ;
12501249 }
12511250
1252- if let Some ( some_other_expr) = other_expr
1253- && let Some ( parent_binop) =
1254- self . infcx . tcx . hir ( ) . parent_iter ( expr. hir_id ) . find_map ( |n| {
1255- if let ( hir_id, hir:: Node :: Expr ( e) ) = n
1256- && let hir:: ExprKind :: AssignOp ( _binop, target, _arg) = e. kind
1257- && target. hir_id == expr. hir_id
1258- {
1259- Some ( hir_id)
1260- } else {
1261- None
1262- }
1263- } )
1264- && let Some ( other_parent_binop) =
1265- self . infcx . tcx . hir ( ) . parent_iter ( some_other_expr. hir_id ) . find_map ( |n| {
1266- if let ( hir_id, hir:: Node :: Expr ( expr) ) = n
1267- && let hir:: ExprKind :: AssignOp ( ..) = expr. kind
1268- {
1269- Some ( hir_id)
1270- } else {
1271- None
1272- }
1273- } )
1274- && parent_binop == other_parent_binop
1275- {
1276- // Explicitly look for `expr += other_expr;` and avoid suggesting
1277- // `expr.clone() += other_expr;`, instead suggesting `expr += other_expr.clone();`.
1278- other_expr = Some ( expr) ;
1279- expr = some_other_expr;
1280- }
1281- ' outer: {
1282- if let ty:: Ref ( ..) = ty. kind ( ) {
1283- // We check for either `let binding = foo(expr, other_expr);` or
1284- // `foo(expr, other_expr);` and if so we don't suggest an incorrect
1285- // `foo(expr, other_expr).clone()`
1286- if let Some ( other_expr) = other_expr
1287- && let Some ( parent_let) =
1288- self . infcx . tcx . hir ( ) . parent_iter ( expr. hir_id ) . find_map ( |n| {
1289- if let ( hir_id, hir:: Node :: LetStmt ( _) | hir:: Node :: Stmt ( _) ) = n {
1290- Some ( hir_id)
1291- } else {
1292- None
1293- }
1294- } )
1295- && let Some ( other_parent_let) =
1296- self . infcx . tcx . hir ( ) . parent_iter ( other_expr. hir_id ) . find_map ( |n| {
1297- if let ( hir_id, hir:: Node :: LetStmt ( _) | hir:: Node :: Stmt ( _) ) = n {
1298- Some ( hir_id)
1299- } else {
1300- None
1301- }
1302- } )
1303- && parent_let == other_parent_let
1304- {
1305- // Explicitly check that we don't have `foo(&*expr, other_expr)`, as cloning the
1306- // result of `foo(...)` won't help.
1307- break ' outer;
1308- }
1309- }
1310- }
1311- let ty = ty. peel_refs ( ) ;
13121251 if self . implements_clone ( ty) {
13131252 self . suggest_cloning_inner ( err, ty, expr) ;
13141253 } else if let ty:: Adt ( def, args) = ty. kind ( )
@@ -1575,10 +1514,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
15751514 ) ;
15761515 self . suggest_copy_for_type_in_cloned_ref ( & mut err, place) ;
15771516 let typeck_results = self . infcx . tcx . typeck ( self . mir_def_id ( ) ) ;
1578- if let Some ( expr) = self . find_expr ( borrow_span)
1579- && let Some ( ty) = typeck_results. node_type_opt ( expr. hir_id )
1580- {
1581- self . suggest_cloning ( & mut err, ty, expr, self . find_expr ( span) , Some ( move_spans) ) ;
1517+ if let Some ( expr) = self . find_expr ( borrow_span) {
1518+ // This is a borrow span, so we want to suggest cloning the referent.
1519+ if let hir:: ExprKind :: AddrOf ( _, _, borrowed_expr) = expr. kind
1520+ && let Some ( ty) = typeck_results. expr_ty_opt ( borrowed_expr)
1521+ {
1522+ self . suggest_cloning ( & mut err, ty, borrowed_expr, Some ( move_spans) ) ;
1523+ } else if typeck_results. expr_adjustments ( expr) . first ( ) . is_some_and ( |adj| {
1524+ matches ! (
1525+ adj. kind,
1526+ ty:: adjustment:: Adjust :: Borrow ( ty:: adjustment:: AutoBorrow :: Ref (
1527+ _,
1528+ ty:: adjustment:: AutoBorrowMutability :: Not
1529+ | ty:: adjustment:: AutoBorrowMutability :: Mut {
1530+ allow_two_phase_borrow: ty:: adjustment:: AllowTwoPhase :: No
1531+ }
1532+ ) )
1533+ )
1534+ } ) && let Some ( ty) = typeck_results. expr_ty_opt ( expr)
1535+ {
1536+ self . suggest_cloning ( & mut err, ty, expr, Some ( move_spans) ) ;
1537+ }
15821538 }
15831539 self . buffer_error ( err) ;
15841540 }
0 commit comments