@@ -563,11 +563,11 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
563563 } = move_spans
564564 && can_suggest_clone
565565 {
566- self . suggest_cloning ( err, ty, expr, None , Some ( move_spans) ) ;
566+ self . suggest_cloning ( err, ty, expr, Some ( move_spans) ) ;
567567 } else if self . suggest_hoisting_call_outside_loop ( err, expr) && can_suggest_clone {
568568 // The place where the type moves would be misleading to suggest clone.
569569 // #121466
570- self . suggest_cloning ( err, ty, expr, None , Some ( move_spans) ) ;
570+ self . suggest_cloning ( err, ty, expr, Some ( move_spans) ) ;
571571 }
572572 }
573573
@@ -1229,8 +1229,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
12291229 & self ,
12301230 err : & mut Diag < ' _ > ,
12311231 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 > ,
12341233 use_spans : Option < UseSpans < ' tcx > > ,
12351234 ) {
12361235 if let hir:: ExprKind :: Struct ( _, _, Some ( _) ) = expr. kind {
@@ -1242,66 +1241,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
12421241 return ;
12431242 }
12441243
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 ( ) ;
13051244 if self . implements_clone ( ty) {
13061245 self . suggest_cloning_inner ( err, ty, expr) ;
13071246 } else if let ty:: Adt ( def, args) = ty. kind ( )
@@ -1573,10 +1512,27 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
15731512 ) ;
15741513 self . suggest_copy_for_type_in_cloned_ref ( & mut err, place) ;
15751514 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+ }
15801536 }
15811537 self . buffer_error ( err) ;
15821538 }
0 commit comments