diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2020-09-13 20:21:05 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-09-13 20:21:05 +0200 |
| commit | 409eb89b3beaab3d962752ee6b024c36dd6cfd31 (patch) | |
| tree | 39fd568bf6e38e7982d5273d996dc54e8ced1030 | |
| parent | 7402a394471a6738a40fea7d4f1891666e5a80c5 (diff) | |
| parent | 5dfe015ba51238e686945d8ce19caf7dee8bc78c (diff) | |
| download | rust-409eb89b3beaab3d962752ee6b024c36dd6cfd31.tar.gz rust-409eb89b3beaab3d962752ee6b024c36dd6cfd31.zip | |
Rollup merge of #75559 - RalfJung:union-test-move, r=joshtriplett
unions: test move behavior of non-Copy fields This test ensures the behaviors suggested by @petrochenkov [here](https://github.com/rust-lang/rust/issues/32836#issuecomment-242511491).
| -rw-r--r-- | src/test/ui/union/union-drop.rs | 7 | ||||
| -rw-r--r-- | src/test/ui/union/union-move.rs | 53 | ||||
| -rw-r--r-- | src/test/ui/union/union-move.stderr | 35 |
3 files changed, 94 insertions, 1 deletions
diff --git a/src/test/ui/union/union-drop.rs b/src/test/ui/union/union-drop.rs index daa03ce6b6f..4df3ed50282 100644 --- a/src/test/ui/union/union-drop.rs +++ b/src/test/ui/union/union-drop.rs @@ -48,6 +48,11 @@ fn main() { { let y = Y { a: S }; } - assert_eq!(CHECK, 2); // 2, dtor of Y is called + assert_eq!(CHECK, 2); // 2, Y has no dtor + { + let u2 = U { a: 1 }; + std::mem::forget(u2); + } + assert_eq!(CHECK, 2); // 2, dtor of U *not* called for u2 } } diff --git a/src/test/ui/union/union-move.rs b/src/test/ui/union/union-move.rs new file mode 100644 index 00000000000..a0a2d0d6598 --- /dev/null +++ b/src/test/ui/union/union-move.rs @@ -0,0 +1,53 @@ +//! Test the behavior of moving out of non-`Copy` union fields. +//! Avoid types that `Drop`, we want to focus on moving. +#![feature(untagged_unions)] + +use std::cell::RefCell; + +fn move_out<T>(x: T) {} + +union U1 { + f1_nocopy: RefCell<i32>, + f2_nocopy: RefCell<i32>, + f3_copy: i32, +} + +union U2 { + f1_nocopy: RefCell<i32>, +} +impl Drop for U2 { + fn drop(&mut self) {} +} + +fn test1(x: U1) { + // Moving out of a nocopy field prevents accessing other nocopy field. + unsafe { + move_out(x.f1_nocopy); + move_out(x.f2_nocopy); //~ ERROR use of moved value: `x` + } +} + +fn test2(x: U1) { + // "Moving" out of copy field doesn't prevent later field accesses. + unsafe { + move_out(x.f3_copy); + move_out(x.f2_nocopy); // no error + } +} + +fn test3(x: U1) { + // Moving out of a nocopy field prevents accessing other copy field. + unsafe { + move_out(x.f2_nocopy); + move_out(x.f3_copy); //~ ERROR use of moved value: `x` + } +} + +fn test4(x: U2) { + // Cannot move out of union that implements `Drop`. + unsafe { + move_out(x.f1_nocopy); //~ ERROR cannot move out of type `U2`, which implements the `Drop` + } +} + +fn main() {} diff --git a/src/test/ui/union/union-move.stderr b/src/test/ui/union/union-move.stderr new file mode 100644 index 00000000000..5679192b641 --- /dev/null +++ b/src/test/ui/union/union-move.stderr @@ -0,0 +1,35 @@ +error[E0382]: use of moved value: `x` + --> $DIR/union-move.rs:26:18 + | +LL | fn test1(x: U1) { + | - move occurs because `x` has type `U1`, which does not implement the `Copy` trait +... +LL | move_out(x.f1_nocopy); + | ----------- value moved here +LL | move_out(x.f2_nocopy); + | ^^^^^^^^^^^ value used here after move + +error[E0382]: use of moved value: `x` + --> $DIR/union-move.rs:42:18 + | +LL | fn test3(x: U1) { + | - move occurs because `x` has type `U1`, which does not implement the `Copy` trait +... +LL | move_out(x.f2_nocopy); + | ----------- value moved here +LL | move_out(x.f3_copy); + | ^^^^^^^^^ value used here after move + +error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait + --> $DIR/union-move.rs:49:18 + | +LL | move_out(x.f1_nocopy); + | ^^^^^^^^^^^ + | | + | cannot move out of here + | move occurs because `x.f1_nocopy` has type `RefCell<i32>`, which does not implement the `Copy` trait + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0382, E0509. +For more information about an error, try `rustc --explain E0382`. |
