unions: test move behavior of non-Copy fields
This commit is contained in:
parent
b6c84553c4
commit
c95fa0ac76
@ -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
|
||||
}
|
||||
}
|
||||
|
53
src/test/ui/union/union-move.rs
Normal file
53
src/test/ui/union/union-move.rs
Normal 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() {}
|
35
src/test/ui/union/union-move.stderr
Normal file
35
src/test/ui/union/union-move.stderr
Normal 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`.
|
Loading…
x
Reference in New Issue
Block a user