Skip to content

Commit 94d68b2

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

32 files changed

+289
-2
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+13-2
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

+6
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

+6
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

+6
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

+6
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

+5
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

+6
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

+5
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

+5
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

+20
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() };

tests/ui/borrowck/move-error-in-promoted-2.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ LL | &([S][0],);
66
| |
77
| cannot move out of here
88
| move occurs because value has type `S`, which does not implement the `Copy` trait
9+
|
10+
note: if `S` implemented `Clone`, you could clone the value
11+
--> $DIR/move-error-in-promoted-2.rs:3:1
12+
|
13+
LL | struct S;
14+
| ^^^^^^^^
915

1016
error: aborting due to 1 previous error
1117

tests/ui/borrowck/move-error-snippets.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ LL | let a = $c;
99
LL | sss!();
1010
| ------ in this macro invocation
1111
|
12+
note: if `A` implemented `Clone`, you could clone the value
13+
--> $DIR/move-error-snippets.rs:9:1
14+
|
15+
LL | struct A;
16+
| ^^^^^^^^
1217
= note: this error originates in the macro `aaa` which comes from the expansion of the macro `sss` (in Nightly builds, run with -Z macro-backtrace for more info)
1318
help: consider borrowing here
1419
|

tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ error[E0507]: cannot move out of a shared reference
33
|
44
LL | static Y: usize = get(*&X);
55
| ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait
6+
|
7+
note: if `Foo` implemented `Clone`, you could clone the value
8+
--> $DIR/move-in-static-initializer-issue-38520.rs:5:1
9+
|
10+
LL | struct Foo(usize);
11+
| ^^^^^^^^^^
612

713
error[E0507]: cannot move out of a shared reference
814
--> $DIR/move-in-static-initializer-issue-38520.rs:13:22
915
|
1016
LL | const Z: usize = get(*&X);
1117
| ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait
18+
|
19+
note: if `Foo` implemented `Clone`, you could clone the value
20+
--> $DIR/move-in-static-initializer-issue-38520.rs:5:1
21+
|
22+
LL | struct Foo(usize);
23+
| ^^^^^^^^^^
1224

1325
error: aborting due to 2 previous errors
1426

tests/ui/box/leak-alloc.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ LL | drop(alloc);
1111
LL |
1212
LL | use_value(*theref)
1313
| ------- borrow later used here
14+
|
15+
note: if `Alloc` implemented `Clone`, you could clone the value
16+
--> $DIR/leak-alloc.rs:8:1
17+
|
18+
LL | struct Alloc {}
19+
| ^^^^^^^^^^^^
1420

1521
error: aborting due to 1 previous error
1622

tests/ui/derives/deriving-with-repr-packed.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ LL | #[repr(packed)]
3636
LL | struct X(Y);
3737
| ^ move occurs because `self.0` has type `Y`, which does not implement the `Copy` trait
3838
|
39+
note: if `Y` implemented `Clone`, you could clone the value
40+
--> $DIR/deriving-with-repr-packed.rs:16:1
41+
|
42+
LL | struct Y(usize);
43+
| ^^^^^^^^
3944
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
4045
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
4146

tests/ui/error-codes/E0504.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ LL | println!("child function: {}", fancy_num.num);
1313
...
1414
LL | println!("main function: {}", fancy_ref.num);
1515
| ------------- borrow later used here
16+
|
17+
note: if `FancyNum` implemented `Clone`, you could clone the value
18+
--> $DIR/E0504.rs:1:1
19+
|
20+
LL | struct FancyNum {
21+
| ^^^^^^^^^^^^^^^
1622

1723
error: aborting due to 1 previous error
1824

tests/ui/error-codes/E0505.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ LL | eat(x);
1010
| ^ move out of `x` occurs here
1111
LL | _ref_to_val.use_ref();
1212
| ----------- borrow later used here
13+
|
14+
note: if `Value` implemented `Clone`, you could clone the value
15+
--> $DIR/E0505.rs:1:1
16+
|
17+
LL | struct Value {}
18+
| ^^^^^^^^^^^^
1319

1420
error: aborting due to 1 previous error
1521

tests/ui/error-codes/E0507.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ note: `TheDarkKnight::nothing_is_true` takes ownership of the receiver `self`, w
1111
|
1212
LL | fn nothing_is_true(self) {}
1313
| ^^^^
14+
note: if `TheDarkKnight` implemented `Clone`, you could clone the value
15+
--> $DIR/E0507.rs:3:1
16+
|
17+
LL | struct TheDarkKnight;
18+
| ^^^^^^^^^^^^^^^^^^^^
1419

1520
error: aborting due to 1 previous error
1621

tests/ui/error-codes/E0508-fail.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ LL | let _value = array[0];
77
| cannot move out of here
88
| move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait
99
|
10+
note: if `NonCopy` implemented `Clone`, you could clone the value
11+
--> $DIR/E0508-fail.rs:1:1
12+
|
13+
LL | struct NonCopy;
14+
| ^^^^^^^^^^^^^^
1015
help: consider borrowing here
1116
|
1217
LL | let _value = &array[0];

tests/ui/error-codes/E0508.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ LL | let _value = array[0];
77
| cannot move out of here
88
| move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait
99
|
10+
note: if `NonCopy` implemented `Clone`, you could clone the value
11+
--> $DIR/E0508.rs:1:1
12+
|
13+
LL | struct NonCopy;
14+
| ^^^^^^^^^^^^^^
1015
help: consider borrowing here
1116
|
1217
LL | let _value = &array[0];

tests/ui/error-codes/E0509.stderr

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ LL | let fancy_field = drop_struct.fancy;
77
| cannot move out of here
88
| move occurs because `drop_struct.fancy` has type `FancyNum`, which does not implement the `Copy` trait
99
|
10+
note: if `FancyNum` implemented `Clone`, you could clone the value
11+
--> $DIR/E0509.rs:1:1
12+
|
13+
LL | struct FancyNum {
14+
| ^^^^^^^^^^^^^^^
1015
help: consider borrowing here
1116
|
1217
LL | let fancy_field = &drop_struct.fancy;

tests/ui/issues/issue-17385.stderr

+12
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ LL | drop(foo);
77
| --- value moved here
88
LL | match foo {
99
| ^^^^^^^^^ value used here after move
10+
|
11+
note: if `X` implemented `Clone`, you could clone the value
12+
--> $DIR/issue-17385.rs:1:1
13+
|
14+
LL | struct X(isize);
15+
| ^^^^^^^^
1016

1117
error[E0382]: use of moved value: `e`
1218
--> $DIR/issue-17385.rs:25:11
@@ -17,6 +23,12 @@ LL | drop(e);
1723
| - value moved here
1824
LL | match e {
1925
| ^ value used here after move
26+
|
27+
note: if `Enum` implemented `Clone`, you could clone the value
28+
--> $DIR/issue-17385.rs:3:1
29+
|
30+
LL | enum Enum {
31+
| ^^^^^^^^^
2032

2133
error: aborting due to 2 previous errors
2234

tests/ui/mir/issue-102389.stderr

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ error[E0507]: cannot move out of `*inbounds` which is behind a shared reference
33
|
44
LL | array[*inbounds as usize]
55
| ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait
6+
|
7+
note: if `Enum` implemented `Clone`, you could clone the value
8+
--> $DIR/issue-102389.rs:1:1
9+
|
10+
LL | enum Enum { A, B, C }
11+
| ^^^^^^^^^
612

713
error: aborting due to 1 previous error
814

0 commit comments

Comments
 (0)