Skip to content

Commit b7b1142

Browse files
committed
Mention when the type of the moved value doesn't implement Clone
1 parent ea3168b commit b7b1142

33 files changed

+299
-8
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -955,8 +955,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
955955
let ty = ty.peel_refs();
956956
if self.implements_clone(ty) {
957957
self.suggest_cloning_inner(err, ty, expr);
958-
// } else {
959-
// err.note(format!("if `{ty}` implemented `Clone`, you could clone the value"));
958+
} else if let ty::Adt(def, args) = ty.kind()
959+
&& def.did().as_local().is_some()
960+
&& def.variants().iter().all(|variant| {
961+
variant
962+
.fields
963+
.iter()
964+
.all(|field| self.implements_clone(field.ty(self.infcx.tcx, args)))
965+
})
966+
{
967+
err.span_note(
968+
self.infcx.tcx.def_span(def.did()),
969+
format!("if `{ty}` implemented `Clone`, you could clone the value"),
970+
);
960971
}
961972
}
962973

tests/ui/associated-types/issue-25700.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ LL | drop(t);
77
| - value moved here
88
LL | drop(t);
99
| ^ value used here after move
10+
|
11+
note: if `S<()>` implemented `Clone`, you could clone the value
12+
--> $DIR/issue-25700.rs:1:1
13+
|
14+
LL | struct S<T: 'static>(#[allow(dead_code)] Option<&'static T>);
15+
| ^^^^^^^^^^^^^^^^^^^^
1016

1117
error: aborting due to 1 previous error
1218

tests/ui/borrowck/borrowck-move-out-of-static-item.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ error[E0507]: cannot move out of static item `BAR`
33
|
44
LL | test(BAR);
55
| ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait
6+
|
7+
note: if `Foo` implemented `Clone`, you could clone the value
8+
--> $DIR/borrowck-move-out-of-static-item.rs:3:1
9+
|
10+
LL | struct Foo {
11+
| ^^^^^^^^^^
612

713
error: aborting due to 1 previous error
814

tests/ui/borrowck/borrowck-move-subcomponent.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ LL | let S { x: ax } = a;
99
| ^^ move out of `a.x` occurs here
1010
LL | f(pb);
1111
| -- borrow later used here
12+
|
13+
note: if `S` implemented `Clone`, you could clone the value
14+
--> $DIR/borrowck-move-subcomponent.rs:6:1
15+
|
16+
LL | struct S {
17+
| ^^^^^^^^
1218

1319
error: aborting due to 1 previous error
1420

tests/ui/borrowck/borrowck-overloaded-call.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ LL | s(" world".to_string());
2929
| - value moved here
3030
LL | s(" world".to_string());
3131
| ^ value used here after move
32+
|
33+
note: if `SFnOnce` implemented `Clone`, you could clone the value
34+
--> $DIR/borrowck-overloaded-call.rs:41:1
35+
|
36+
LL | struct SFnOnce {
37+
| ^^^^^^^^^^^^^^
3238

3339
error: aborting due to 3 previous errors
3440

tests/ui/borrowck/clone-on-ref.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ LL |
5252
LL | println!("{b:?}");
5353
| ----- borrow later used here
5454
|
55+
note: if `A` implemented `Clone`, you could clone the value
56+
--> $DIR/clone-on-ref.rs:19:1
57+
|
58+
LL | struct A;
59+
| ^^^^^^^^
5560
help: consider annotating `A` with `#[derive(Clone)]`
5661
|
5762
LL + #[derive(Clone)]

tests/ui/borrowck/issue-103624.stderr

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ LL | spawn_blocking(move || {
99
LL |
1010
LL | self.b;
1111
| ^^^^^^ move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
12+
|
13+
note: if `StructB` implemented `Clone`, you could clone the value
14+
--> $DIR/issue-103624.rs:23:1
15+
|
16+
LL | struct StructB {}
17+
| ^^^^^^^^^^^^^^
1218

1319
error[E0521]: borrowed data escapes outside of method
1420
--> $DIR/issue-103624.rs:14:9

tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ note: `Example::<E, FakeParam>::change` takes ownership of the receiver `self`,
1111
|
1212
LL | unsafe fn change<NewFakeParam>(self) -> Example<E, NewFakeParam> {
1313
| ^^^^
14+
note: if `Example<E, NoLifetime>` implemented `Clone`, you could clone the value
15+
--> $DIR/issue-119915-bad-clone-suggestion.rs:3:1
16+
|
17+
LL | struct Example<E, FakeParam>(PhantomData<(fn(E), fn(FakeParam))>);
18+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1419

1520
error: aborting due to 1 previous error
1621

tests/ui/borrowck/issue-17718-static-move.stderr

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ error[E0507]: cannot move out of static item `FOO`
44
LL | let _a = FOO;
55
| ^^^ move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait
66
|
7+
note: if `Foo` implemented `Clone`, you could clone the value
8+
--> $DIR/issue-17718-static-move.rs:1:1
9+
|
10+
LL | struct Foo;
11+
| ^^^^^^^^^^
712
help: consider borrowing here
813
|
914
LL | let _a = &FOO;

tests/ui/borrowck/issue-20801.stderr

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ error[E0507]: cannot move out of a mutable reference
1919
LL | let a = unsafe { *mut_ref() };
2020
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
2121
|
22+
note: if `T` implemented `Clone`, you could clone the value
23+
--> $DIR/issue-20801.rs:3:1
24+
|
25+
LL | struct T(u8);
26+
| ^^^^^^^^
2227
help: consider removing the dereference here
2328
|
2429
LL - let a = unsafe { *mut_ref() };
@@ -31,6 +36,11 @@ error[E0507]: cannot move out of a shared reference
3136
LL | let b = unsafe { *imm_ref() };
3237
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
3338
|
39+
note: if `T` implemented `Clone`, you could clone the value
40+
--> $DIR/issue-20801.rs:3:1
41+
|
42+
LL | struct T(u8);
43+
| ^^^^^^^^
3444
help: consider removing the dereference here
3545
|
3646
LL - let b = unsafe { *imm_ref() };
@@ -43,6 +53,11 @@ error[E0507]: cannot move out of a raw pointer
4353
LL | let c = unsafe { *mut_ptr() };
4454
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
4555
|
56+
note: if `T` implemented `Clone`, you could clone the value
57+
--> $DIR/issue-20801.rs:3:1
58+
|
59+
LL | struct T(u8);
60+
| ^^^^^^^^
4661
help: consider removing the dereference here
4762
|
4863
LL - let c = unsafe { *mut_ptr() };
@@ -55,6 +70,11 @@ error[E0507]: cannot move out of a raw pointer
5570
LL | let d = unsafe { *const_ptr() };
5671
| ^^^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
5772
|
73+
note: if `T` implemented `Clone`, you could clone the value
74+
--> $DIR/issue-20801.rs:3:1
75+
|
76+
LL | struct T(u8);
77+
| ^^^^^^^^
5878
help: consider removing the dereference here
5979
|
6080
LL - let d = unsafe { *const_ptr() };

0 commit comments

Comments
 (0)