Skip to content

Commit 5c63884

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 db93ff1 commit 5c63884

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
@@ -751,9 +751,39 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
751751
&self,
752752
err: &mut Diag<'_>,
753753
ty: Ty<'tcx>,
754-
expr: &hir::Expr<'_>,
755-
other_expr: Option<&hir::Expr<'_>>,
754+
mut expr: &'cx hir::Expr<'cx>,
755+
mut other_expr: Option<&'cx hir::Expr<'cx>>,
756756
) {
757+
if let Some(some_other_expr) = other_expr
758+
&& let Some(parent_binop) =
759+
self.infcx.tcx.hir().parent_iter(expr.hir_id).find_map(|n| {
760+
if let (hir_id, hir::Node::Expr(e)) = n
761+
&& let hir::ExprKind::AssignOp(_binop, target, _arg) = e.kind
762+
&& target.hir_id == expr.hir_id
763+
{
764+
Some(hir_id)
765+
} else {
766+
None
767+
}
768+
})
769+
&& let Some(other_parent_binop) =
770+
self.infcx.tcx.hir().parent_iter(some_other_expr.hir_id).find_map(|n| {
771+
if let (hir_id, hir::Node::Expr(expr)) = n
772+
&& let hir::ExprKind::AssignOp(..) = expr.kind
773+
{
774+
Some(hir_id)
775+
} else {
776+
None
777+
}
778+
})
779+
&& { true }
780+
&& parent_binop == other_parent_binop
781+
{
782+
// Explicitly look for `expr += other_expr;` and avoid suggesting
783+
// `expr.clone() += other_expr;`, instead suggesting `expr += other_expr.clone();`.
784+
other_expr = Some(expr);
785+
expr = some_other_expr;
786+
}
757787
'outer: {
758788
if let ty::Ref(..) = ty.kind() {
759789
// 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)