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();`.
This commit is contained in:
parent
b83ebea5de
commit
dfe28debb9
@ -991,9 +991,39 @@ pub(crate) fn suggest_cloning(
|
|||||||
&self,
|
&self,
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
expr: &hir::Expr<'_>,
|
mut expr: &'cx hir::Expr<'cx>,
|
||||||
other_expr: Option<&hir::Expr<'_>>,
|
mut other_expr: Option<&'cx hir::Expr<'cx>>,
|
||||||
) {
|
) {
|
||||||
|
if let Some(some_other_expr) = other_expr
|
||||||
|
&& let Some(parent_binop) =
|
||||||
|
self.infcx.tcx.hir().parent_iter(expr.hir_id).find_map(|n| {
|
||||||
|
if let (hir_id, hir::Node::Expr(e)) = n
|
||||||
|
&& let hir::ExprKind::AssignOp(_binop, target, _arg) = e.kind
|
||||||
|
&& target.hir_id == expr.hir_id
|
||||||
|
{
|
||||||
|
Some(hir_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
&& let Some(other_parent_binop) =
|
||||||
|
self.infcx.tcx.hir().parent_iter(some_other_expr.hir_id).find_map(|n| {
|
||||||
|
if let (hir_id, hir::Node::Expr(expr)) = n
|
||||||
|
&& let hir::ExprKind::AssignOp(..) = expr.kind
|
||||||
|
{
|
||||||
|
Some(hir_id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
&& { true }
|
||||||
|
&& parent_binop == other_parent_binop
|
||||||
|
{
|
||||||
|
// Explicitly look for `expr += other_expr;` and avoid suggesting
|
||||||
|
// `expr.clone() += other_expr;`, instead suggesting `expr += other_expr.clone();`.
|
||||||
|
other_expr = Some(expr);
|
||||||
|
expr = some_other_expr;
|
||||||
|
}
|
||||||
'outer: {
|
'outer: {
|
||||||
if let ty::Ref(..) = ty.kind() {
|
if let ty::Ref(..) = ty.kind() {
|
||||||
// We check for either `let binding = foo(expr, other_expr);` or
|
// We check for either `let binding = foo(expr, other_expr);` or
|
||||||
|
@ -13,11 +13,11 @@ fn main() {
|
|||||||
let mut x = Int(1); //~ NOTE binding `x` declared here
|
let mut x = Int(1); //~ NOTE binding `x` declared here
|
||||||
x
|
x
|
||||||
//~^ NOTE borrow of `x` occurs here
|
//~^ NOTE borrow of `x` occurs here
|
||||||
//~| HELP consider cloning
|
|
||||||
+=
|
+=
|
||||||
x;
|
x;
|
||||||
//~^ ERROR cannot move out of `x` because it is borrowed
|
//~^ ERROR cannot move out of `x` because it is borrowed
|
||||||
//~| move out of `x` occurs here
|
//~| move out of `x` occurs here
|
||||||
|
//~| HELP consider cloning
|
||||||
|
|
||||||
let y = Int(2);
|
let y = Int(2);
|
||||||
//~^ HELP consider changing this to be mutable
|
//~^ HELP consider changing this to be mutable
|
||||||
|
@ -11,7 +11,7 @@ LL | x;
|
|||||||
|
|
|
|
||||||
help: consider cloning the value if the performance cost is acceptable
|
help: consider cloning the value if the performance cost is acceptable
|
||||||
|
|
|
|
||||||
LL | x.clone()
|
LL | x.clone();
|
||||||
| ++++++++
|
| ++++++++
|
||||||
|
|
||||||
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
|
error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable
|
||||||
|
Loading…
Reference in New Issue
Block a user