Skip to content

Commit dfe28de

Browse files
committed
Account for assign binops in clone suggestions
Explicitly look for `expr += other_expr;` and avoid suggesting `expr.clone() += other_expr;`, instead suggesting `expr += other_expr.clone();`.
1 parent b83ebea commit dfe28de

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -991,9 +991,39 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
991991
&self,
992992
err: &mut Diag<'_>,
993993
ty: Ty<'tcx>,
994-
expr: &hir::Expr<'_>,
995-
other_expr: Option<&hir::Expr<'_>>,
994+
mut expr: &'cx hir::Expr<'cx>,
995+
mut other_expr: Option<&'cx hir::Expr<'cx>>,
996996
) {
997+
if let Some(some_other_expr) = other_expr
998+
&& let Some(parent_binop) =
999+
self.infcx.tcx.hir().parent_iter(expr.hir_id).find_map(|n| {
1000+
if let (hir_id, hir::Node::Expr(e)) = n
1001+
&& let hir::ExprKind::AssignOp(_binop, target, _arg) = e.kind
1002+
&& target.hir_id == expr.hir_id
1003+
{
1004+
Some(hir_id)
1005+
} else {
1006+
None
1007+
}
1008+
})
1009+
&& let Some(other_parent_binop) =
1010+
self.infcx.tcx.hir().parent_iter(some_other_expr.hir_id).find_map(|n| {
1011+
if let (hir_id, hir::Node::Expr(expr)) = n
1012+
&& let hir::ExprKind::AssignOp(..) = expr.kind
1013+
{
1014+
Some(hir_id)
1015+
} else {
1016+
None
1017+
}
1018+
})
1019+
&& { true }
1020+
&& parent_binop == other_parent_binop
1021+
{
1022+
// Explicitly look for `expr += other_expr;` and avoid suggesting
1023+
// `expr.clone() += other_expr;`, instead suggesting `expr += other_expr.clone();`.
1024+
other_expr = Some(expr);
1025+
expr = some_other_expr;
1026+
}
9971027
'outer: {
9981028
if let ty::Ref(..) = ty.kind() {
9991029
// We check for either `let binding = foo(expr, other_expr);` or

tests/ui/augmented-assignments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ fn main() {
1313
let mut x = Int(1); //~ NOTE binding `x` declared here
1414
x
1515
//~^ NOTE borrow of `x` occurs here
16-
//~| HELP consider cloning
1716
+=
1817
x;
1918
//~^ ERROR cannot move out of `x` because it is borrowed
2019
//~| move out of `x` occurs here
20+
//~| HELP consider cloning
2121

2222
let y = Int(2);
2323
//~^ HELP consider changing this to be mutable

tests/ui/augmented-assignments.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ LL | x;
1111
|
1212
help: consider cloning the value if the performance cost is acceptable
1313
|
14-
LL | x.clone()
14+
LL | x.clone();
1515
| ++++++++
1616

1717
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable

0 commit comments

Comments
 (0)