Skip to content

Commit

Permalink
Mention when the type of the moved value doesn't implement Clone
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Mar 17, 2024
1 parent ea3168b commit 94d68b2
Show file tree
Hide file tree
Showing 32 changed files with 289 additions and 2 deletions.
15 changes: 13 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -955,8 +955,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let ty = ty.peel_refs();
if self.implements_clone(ty) {
self.suggest_cloning_inner(err, ty, expr);
// } else {
// err.note(format!("if `{ty}` implemented `Clone`, you could clone the value"));
} else if let ty::Adt(def, args) = ty.kind()
&& def.did().as_local().is_some()
&& def.variants().iter().all(|variant| {
variant
.fields
.iter()
.all(|field| self.implements_clone(field.ty(self.infcx.tcx, args)))
})
{
err.span_note(
self.infcx.tcx.def_span(def.did()),
format!("if `{ty}` implemented `Clone`, you could clone the value"),
);
}
}

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/associated-types/issue-25700.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ LL | drop(t);
| - value moved here
LL | drop(t);
| ^ value used here after move
|
note: if `S<()>` implemented `Clone`, you could clone the value
--> $DIR/issue-25700.rs:1:1
|
LL | struct S<T: 'static>(#[allow(dead_code)] Option<&'static T>);
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/borrowck/borrowck-move-out-of-static-item.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ error[E0507]: cannot move out of static item `BAR`
|
LL | test(BAR);
| ^^^ move occurs because `BAR` has type `Foo`, which does not implement the `Copy` trait
|
note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/borrowck-move-out-of-static-item.rs:3:1
|
LL | struct Foo {
| ^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/borrowck/borrowck-move-subcomponent.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ LL | let S { x: ax } = a;
| ^^ move out of `a.x` occurs here
LL | f(pb);
| -- borrow later used here
|
note: if `S` implemented `Clone`, you could clone the value
--> $DIR/borrowck-move-subcomponent.rs:6:1
|
LL | struct S {
| ^^^^^^^^

error: aborting due to 1 previous error

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/borrowck/borrowck-overloaded-call.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ LL | s(" world".to_string());
| - value moved here
LL | s(" world".to_string());
| ^ value used here after move
|
note: if `SFnOnce` implemented `Clone`, you could clone the value
--> $DIR/borrowck-overloaded-call.rs:41:1
|
LL | struct SFnOnce {
| ^^^^^^^^^^^^^^

error: aborting due to 3 previous errors

Expand Down
5 changes: 5 additions & 0 deletions tests/ui/borrowck/clone-on-ref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ LL |
LL | println!("{b:?}");
| ----- borrow later used here
|
note: if `A` implemented `Clone`, you could clone the value
--> $DIR/clone-on-ref.rs:19:1
|
LL | struct A;
| ^^^^^^^^
help: consider annotating `A` with `#[derive(Clone)]`
|
LL + #[derive(Clone)]
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/borrowck/issue-103624.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ LL | spawn_blocking(move || {
LL |
LL | self.b;
| ^^^^^^ move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
|
note: if `StructB` implemented `Clone`, you could clone the value
--> $DIR/issue-103624.rs:23:1
|
LL | struct StructB {}
| ^^^^^^^^^^^^^^

error[E0521]: borrowed data escapes outside of method
--> $DIR/issue-103624.rs:14:9
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/borrowck/issue-119915-bad-clone-suggestion.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ note: `Example::<E, FakeParam>::change` takes ownership of the receiver `self`,
|
LL | unsafe fn change<NewFakeParam>(self) -> Example<E, NewFakeParam> {
| ^^^^
note: if `Example<E, NoLifetime>` implemented `Clone`, you could clone the value
--> $DIR/issue-119915-bad-clone-suggestion.rs:3:1
|
LL | struct Example<E, FakeParam>(PhantomData<(fn(E), fn(FakeParam))>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
5 changes: 5 additions & 0 deletions tests/ui/borrowck/issue-17718-static-move.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ error[E0507]: cannot move out of static item `FOO`
LL | let _a = FOO;
| ^^^ move occurs because `FOO` has type `Foo`, which does not implement the `Copy` trait
|
note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/issue-17718-static-move.rs:1:1
|
LL | struct Foo;
| ^^^^^^^^^^
help: consider borrowing here
|
LL | let _a = &FOO;
Expand Down
20 changes: 20 additions & 0 deletions tests/ui/borrowck/issue-20801.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ error[E0507]: cannot move out of a mutable reference
LL | let a = unsafe { *mut_ref() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
|
note: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-20801.rs:3:1
|
LL | struct T(u8);
| ^^^^^^^^
help: consider removing the dereference here
|
LL - let a = unsafe { *mut_ref() };
Expand All @@ -31,6 +36,11 @@ error[E0507]: cannot move out of a shared reference
LL | let b = unsafe { *imm_ref() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
|
note: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-20801.rs:3:1
|
LL | struct T(u8);
| ^^^^^^^^
help: consider removing the dereference here
|
LL - let b = unsafe { *imm_ref() };
Expand All @@ -43,6 +53,11 @@ error[E0507]: cannot move out of a raw pointer
LL | let c = unsafe { *mut_ptr() };
| ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
|
note: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-20801.rs:3:1
|
LL | struct T(u8);
| ^^^^^^^^
help: consider removing the dereference here
|
LL - let c = unsafe { *mut_ptr() };
Expand All @@ -55,6 +70,11 @@ error[E0507]: cannot move out of a raw pointer
LL | let d = unsafe { *const_ptr() };
| ^^^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
|
note: if `T` implemented `Clone`, you could clone the value
--> $DIR/issue-20801.rs:3:1
|
LL | struct T(u8);
| ^^^^^^^^
help: consider removing the dereference here
|
LL - let d = unsafe { *const_ptr() };
Expand Down
6 changes: 6 additions & 0 deletions tests/ui/borrowck/move-error-in-promoted-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ LL | &([S][0],);
| |
| cannot move out of here
| move occurs because value has type `S`, which does not implement the `Copy` trait
|
note: if `S` implemented `Clone`, you could clone the value
--> $DIR/move-error-in-promoted-2.rs:3:1
|
LL | struct S;
| ^^^^^^^^

error: aborting due to 1 previous error

Expand Down
5 changes: 5 additions & 0 deletions tests/ui/borrowck/move-error-snippets.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ LL | let a = $c;
LL | sss!();
| ------ in this macro invocation
|
note: if `A` implemented `Clone`, you could clone the value
--> $DIR/move-error-snippets.rs:9:1
|
LL | struct A;
| ^^^^^^^^
= 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)
help: consider borrowing here
|
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/borrowck/move-in-static-initializer-issue-38520.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,24 @@ error[E0507]: cannot move out of a shared reference
|
LL | static Y: usize = get(*&X);
| ^^^ move occurs because value has type `Foo`, which does not implement the `Copy` trait
|
note: if `Foo` implemented `Clone`, you could clone the value
--> $DIR/move-in-static-initializer-issue-38520.rs:5:1
|
LL | struct Foo(usize);
| ^^^^^^^^^^

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

error: aborting due to 2 previous errors

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/box/leak-alloc.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ LL | drop(alloc);
LL |
LL | use_value(*theref)
| ------- borrow later used here
|
note: if `Alloc` implemented `Clone`, you could clone the value
--> $DIR/leak-alloc.rs:8:1
|
LL | struct Alloc {}
| ^^^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
5 changes: 5 additions & 0 deletions tests/ui/derives/deriving-with-repr-packed.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ LL | #[repr(packed)]
LL | struct X(Y);
| ^ move occurs because `self.0` has type `Y`, which does not implement the `Copy` trait
|
note: if `Y` implemented `Clone`, you could clone the value
--> $DIR/deriving-with-repr-packed.rs:16:1
|
LL | struct Y(usize);
| ^^^^^^^^
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/error-codes/E0504.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ LL | println!("child function: {}", fancy_num.num);
...
LL | println!("main function: {}", fancy_ref.num);
| ------------- borrow later used here
|
note: if `FancyNum` implemented `Clone`, you could clone the value
--> $DIR/E0504.rs:1:1
|
LL | struct FancyNum {
| ^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/error-codes/E0505.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ LL | eat(x);
| ^ move out of `x` occurs here
LL | _ref_to_val.use_ref();
| ----------- borrow later used here
|
note: if `Value` implemented `Clone`, you could clone the value
--> $DIR/E0505.rs:1:1
|
LL | struct Value {}
| ^^^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
5 changes: 5 additions & 0 deletions tests/ui/error-codes/E0507.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ note: `TheDarkKnight::nothing_is_true` takes ownership of the receiver `self`, w
|
LL | fn nothing_is_true(self) {}
| ^^^^
note: if `TheDarkKnight` implemented `Clone`, you could clone the value
--> $DIR/E0507.rs:3:1
|
LL | struct TheDarkKnight;
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
5 changes: 5 additions & 0 deletions tests/ui/error-codes/E0508-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ LL | let _value = array[0];
| cannot move out of here
| move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait
|
note: if `NonCopy` implemented `Clone`, you could clone the value
--> $DIR/E0508-fail.rs:1:1
|
LL | struct NonCopy;
| ^^^^^^^^^^^^^^
help: consider borrowing here
|
LL | let _value = &array[0];
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/error-codes/E0508.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ LL | let _value = array[0];
| cannot move out of here
| move occurs because `array[_]` has type `NonCopy`, which does not implement the `Copy` trait
|
note: if `NonCopy` implemented `Clone`, you could clone the value
--> $DIR/E0508.rs:1:1
|
LL | struct NonCopy;
| ^^^^^^^^^^^^^^
help: consider borrowing here
|
LL | let _value = &array[0];
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/error-codes/E0509.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ LL | let fancy_field = drop_struct.fancy;
| cannot move out of here
| move occurs because `drop_struct.fancy` has type `FancyNum`, which does not implement the `Copy` trait
|
note: if `FancyNum` implemented `Clone`, you could clone the value
--> $DIR/E0509.rs:1:1
|
LL | struct FancyNum {
| ^^^^^^^^^^^^^^^
help: consider borrowing here
|
LL | let fancy_field = &drop_struct.fancy;
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/issues/issue-17385.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ LL | drop(foo);
| --- value moved here
LL | match foo {
| ^^^^^^^^^ value used here after move
|
note: if `X` implemented `Clone`, you could clone the value
--> $DIR/issue-17385.rs:1:1
|
LL | struct X(isize);
| ^^^^^^^^

error[E0382]: use of moved value: `e`
--> $DIR/issue-17385.rs:25:11
Expand All @@ -17,6 +23,12 @@ LL | drop(e);
| - value moved here
LL | match e {
| ^ value used here after move
|
note: if `Enum` implemented `Clone`, you could clone the value
--> $DIR/issue-17385.rs:3:1
|
LL | enum Enum {
| ^^^^^^^^^

error: aborting due to 2 previous errors

Expand Down
6 changes: 6 additions & 0 deletions tests/ui/mir/issue-102389.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ error[E0507]: cannot move out of `*inbounds` which is behind a shared reference
|
LL | array[*inbounds as usize]
| ^^^^^^^^^ move occurs because `*inbounds` has type `Enum`, which does not implement the `Copy` trait
|
note: if `Enum` implemented `Clone`, you could clone the value
--> $DIR/issue-102389.rs:1:1
|
LL | enum Enum { A, B, C }
| ^^^^^^^^^

error: aborting due to 1 previous error

Expand Down
Loading

0 comments on commit 94d68b2

Please sign in to comment.