Skip to content

Commit 1964b93

Browse files
committed
Account for unops when suggesting cloning
1 parent 2311ecb commit 1964b93

27 files changed

+134
-93
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,27 +1024,32 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10241024
} else {
10251025
".clone()".to_owned()
10261026
};
1027-
if let Some(clone_trait_def) = tcx.lang_items().clone_trait()
1028-
&& self
1029-
.infcx
1030-
.type_implements_trait(clone_trait_def, [ty], self.param_env)
1031-
.must_apply_modulo_regions()
1027+
let mut sugg = Vec::with_capacity(2);
1028+
let mut inner_expr = expr;
1029+
while let hir::ExprKind::AddrOf(.., inner) | hir::ExprKind::Unary(hir::UnOp::Deref, inner) =
1030+
&inner_expr.kind
10321031
{
1033-
let msg = if let ty::Adt(def, _) = ty.kind()
1034-
&& [tcx.get_diagnostic_item(sym::Arc), tcx.get_diagnostic_item(sym::Rc)]
1035-
.contains(&Some(def.did()))
1036-
{
1037-
"clone the value to increment its reference count"
1038-
} else {
1039-
"consider cloning the value if the performance cost is acceptable"
1040-
};
1041-
err.span_suggestion_verbose(
1042-
span.shrink_to_hi(),
1043-
msg,
1044-
suggestion,
1045-
Applicability::MachineApplicable,
1046-
);
1032+
inner_expr = inner;
10471033
}
1034+
if inner_expr.span.lo() != expr.span.lo() {
1035+
sugg.push((expr.span.with_hi(inner_expr.span.lo()), String::new()));
1036+
}
1037+
let span = if inner_expr.span.hi() != expr.span.hi() {
1038+
// Account for `(*x)` to suggest `x.clone()`.
1039+
expr.span.with_lo(inner_expr.span.hi())
1040+
} else {
1041+
span.shrink_to_hi()
1042+
};
1043+
sugg.push((span, suggestion));
1044+
let msg = if let ty::Adt(def, _) = ty.kind()
1045+
&& [tcx.get_diagnostic_item(sym::Arc), tcx.get_diagnostic_item(sym::Rc)]
1046+
.contains(&Some(def.did()))
1047+
{
1048+
"clone the value to increment its reference count"
1049+
} else {
1050+
"consider cloning the value if the performance cost is acceptable"
1051+
};
1052+
err.multipart_suggestion_verbose(msg, sugg, Applicability::MachineApplicable);
10481053
}
10491054

10501055
fn suggest_adding_bounds(&self, err: &mut Diag<'_>, ty: Ty<'tcx>, def_id: DefId, span: Span) {

tests/ui/associated-types/associated-types-outlives.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ LL | return f(y);
1313
|
1414
help: consider cloning the value if the performance cost is acceptable
1515
|
16-
LL | 's: loop { y = denormalise(&x.clone()); break }
17-
| ++++++++
16+
LL - 's: loop { y = denormalise(&x); break }
17+
LL + 's: loop { y = denormalise(x.clone()); break }
18+
|
1819

1920
error: aborting due to 1 previous error
2021

tests/ui/binop/binop-move-semantics.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ LL | use_mut(n); use_imm(m);
5454
|
5555
help: consider cloning the value if the performance cost is acceptable
5656
|
57-
LL | let m = &x.clone();
58-
| ++++++++
57+
LL - let m = &x;
58+
LL + let m = x.clone();
59+
|
5960

6061
error[E0505]: cannot move out of `y` because it is borrowed
6162
--> $DIR/binop-move-semantics.rs:23:5

tests/ui/borrowck/borrow-tuple-fields.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ LL | r.use_ref();
1313
|
1414
help: consider cloning the value if the performance cost is acceptable
1515
|
16-
LL | let r = &x.0.clone();
17-
| ++++++++
16+
LL - let r = &x.0;
17+
LL + let r = x.0.clone();
18+
|
1819

1920
error[E0502]: cannot borrow `x.0` as mutable because it is also borrowed as immutable
2021
--> $DIR/borrow-tuple-fields.rs:18:13
@@ -50,8 +51,9 @@ LL | r.use_ref();
5051
|
5152
help: consider cloning the value if the performance cost is acceptable
5253
|
53-
LL | let r = &x.0.clone();
54-
| ++++++++
54+
LL - let r = &x.0;
55+
LL + let r = x.0.clone();
56+
|
5557

5658
error[E0502]: cannot borrow `x.0` as mutable because it is also borrowed as immutable
5759
--> $DIR/borrow-tuple-fields.rs:33:13

tests/ui/borrowck/borrowck-bad-nested-calls-move.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ LL | a);
1313
|
1414
help: consider cloning the value if the performance cost is acceptable
1515
|
16-
LL | &*a.clone(),
17-
| ++++++++
16+
LL - &*a,
17+
LL + a.clone(),
18+
|
1819

1920
error[E0505]: cannot move out of `a` because it is borrowed
2021
--> $DIR/borrowck-bad-nested-calls-move.rs:32:9
@@ -30,8 +31,9 @@ LL | a);
3031
|
3132
help: consider cloning the value if the performance cost is acceptable
3233
|
33-
LL | &*a.clone(),
34-
| ++++++++
34+
LL - &*a,
35+
LL + a.clone(),
36+
|
3537

3638
error: aborting due to 2 previous errors
3739

tests/ui/borrowck/borrowck-field-sensitivity.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ LL | drop(**p);
5252
|
5353
help: consider cloning the value if the performance cost is acceptable
5454
|
55-
LL | let p = &x.b.clone();
56-
| ++++++++
55+
LL - let p = &x.b;
56+
LL + let p = x.b.clone();
57+
|
5758

5859
error[E0505]: cannot move out of `x.b` because it is borrowed
5960
--> $DIR/borrowck-field-sensitivity.rs:41:14
@@ -69,8 +70,9 @@ LL | drop(**p);
6970
|
7071
help: consider cloning the value if the performance cost is acceptable
7172
|
72-
LL | let p = &x.b.clone();
73-
| ++++++++
73+
LL - let p = &x.b;
74+
LL + let p = x.b.clone();
75+
|
7476

7577
error[E0499]: cannot borrow `x.a` as mutable more than once at a time
7678
--> $DIR/borrowck-field-sensitivity.rs:48:13

tests/ui/borrowck/borrowck-loan-blocks-move-cc.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ LL | w.use_ref();
1616
|
1717
help: consider cloning the value if the performance cost is acceptable
1818
|
19-
LL | let w = &v.clone();
20-
| ++++++++
19+
LL - let w = &v;
20+
LL + let w = v.clone();
21+
|
2122

2223
error[E0505]: cannot move out of `v` because it is borrowed
2324
--> $DIR/borrowck-loan-blocks-move-cc.rs:24:19
@@ -37,8 +38,9 @@ LL | w.use_ref();
3738
|
3839
help: consider cloning the value if the performance cost is acceptable
3940
|
40-
LL | let w = &v.clone();
41-
| ++++++++
41+
LL - let w = &v;
42+
LL + let w = v.clone();
43+
|
4244

4345
error: aborting due to 2 previous errors
4446

tests/ui/borrowck/borrowck-loan-blocks-move.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ LL | w.use_ref();
1212
|
1313
help: consider cloning the value if the performance cost is acceptable
1414
|
15-
LL | let w = &v.clone();
16-
| ++++++++
15+
LL - let w = &v;
16+
LL + let w = v.clone();
17+
|
1718

1819
error: aborting due to 1 previous error
1920

tests/ui/borrowck/borrowck-move-from-subpath-of-borrowed-path.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ LL | b.use_ref();
1313
|
1414
help: consider cloning the value if the performance cost is acceptable
1515
|
16-
LL | let b = &a.clone();
17-
| ++++++++
16+
LL - let b = &a;
17+
LL + let b = a.clone();
18+
|
1819

1920
error: aborting due to 1 previous error
2021

tests/ui/borrowck/borrowck-move-mut-base-ptr.stderr

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ LL | p.use_ref();
1313
|
1414
help: consider cloning the value if the performance cost is acceptable
1515
|
16-
LL | let p: &isize = &*t0.clone(); // Freezes `*t0`
17-
| ++++++++
16+
LL - let p: &isize = &*t0; // Freezes `*t0`
17+
LL + let p: &isize = t0.clone(); // Freezes `*t0`
18+
|
1819

1920
error: aborting due to 1 previous error
2021

0 commit comments

Comments
 (0)