unions: test move behavior of non-Copy fields

This commit is contained in:
Ralf Jung 2020-08-15 13:04:32 +02:00
parent b6c84553c4
commit c95fa0ac76
3 changed files with 93 additions and 0 deletions

View file

@ -49,5 +49,10 @@ fn main() {
let y = Y { a: S };
}
assert_eq!(CHECK, 2); // 2, dtor of Y is called
{
let y2 = Y { a: S };
std::mem::forget(y2);
}
assert_eq!(CHECK, 2); // 2, dtor of Y *not* called for y2
}
}

View file

@ -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` trait
}
}
fn main() {}

View file

@ -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 `std::cell::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`.