File tree 3 files changed +94
-1
lines changed
3 files changed +94
-1
lines changed Original file line number Diff line number Diff line change @@ -48,6 +48,11 @@ fn main() {
48
48
{
49
49
let y = Y { a : S } ;
50
50
}
51
- assert_eq ! ( CHECK , 2 ) ; // 2, dtor of Y is called
51
+ assert_eq ! ( CHECK , 2 ) ; // 2, Y has no dtor
52
+ {
53
+ let u2 = U { a : 1 } ;
54
+ std:: mem:: forget ( u2) ;
55
+ }
56
+ assert_eq ! ( CHECK , 2 ) ; // 2, dtor of U *not* called for u2
52
57
}
53
58
}
Original file line number Diff line number Diff line change
1
+ //! Test the behavior of moving out of non-`Copy` union fields.
2
+ //! Avoid types that `Drop`, we want to focus on moving.
3
+ #![ feature( untagged_unions) ]
4
+
5
+ use std:: cell:: RefCell ;
6
+
7
+ fn move_out < T > ( x : T ) { }
8
+
9
+ union U1 {
10
+ f1_nocopy : RefCell < i32 > ,
11
+ f2_nocopy : RefCell < i32 > ,
12
+ f3_copy : i32 ,
13
+ }
14
+
15
+ union U2 {
16
+ f1_nocopy : RefCell < i32 > ,
17
+ }
18
+ impl Drop for U2 {
19
+ fn drop ( & mut self ) { }
20
+ }
21
+
22
+ fn test1 ( x : U1 ) {
23
+ // Moving out of a nocopy field prevents accessing other nocopy field.
24
+ unsafe {
25
+ move_out ( x. f1_nocopy ) ;
26
+ move_out ( x. f2_nocopy ) ; //~ ERROR use of moved value: `x`
27
+ }
28
+ }
29
+
30
+ fn test2 ( x : U1 ) {
31
+ // "Moving" out of copy field doesn't prevent later field accesses.
32
+ unsafe {
33
+ move_out ( x. f3_copy ) ;
34
+ move_out ( x. f2_nocopy ) ; // no error
35
+ }
36
+ }
37
+
38
+ fn test3 ( x : U1 ) {
39
+ // Moving out of a nocopy field prevents accessing other copy field.
40
+ unsafe {
41
+ move_out ( x. f2_nocopy ) ;
42
+ move_out ( x. f3_copy ) ; //~ ERROR use of moved value: `x`
43
+ }
44
+ }
45
+
46
+ fn test4 ( x : U2 ) {
47
+ // Cannot move out of union that implements `Drop`.
48
+ unsafe {
49
+ move_out ( x. f1_nocopy ) ; //~ ERROR cannot move out of type `U2`, which implements the `Drop`
50
+ }
51
+ }
52
+
53
+ fn main ( ) { }
Original file line number Diff line number Diff line change
1
+ error[E0382]: use of moved value: `x`
2
+ --> $DIR/union-move.rs:26:18
3
+ |
4
+ LL | fn test1(x: U1) {
5
+ | - move occurs because `x` has type `U1`, which does not implement the `Copy` trait
6
+ ...
7
+ LL | move_out(x.f1_nocopy);
8
+ | ----------- value moved here
9
+ LL | move_out(x.f2_nocopy);
10
+ | ^^^^^^^^^^^ value used here after move
11
+
12
+ error[E0382]: use of moved value: `x`
13
+ --> $DIR/union-move.rs:42:18
14
+ |
15
+ LL | fn test3(x: U1) {
16
+ | - move occurs because `x` has type `U1`, which does not implement the `Copy` trait
17
+ ...
18
+ LL | move_out(x.f2_nocopy);
19
+ | ----------- value moved here
20
+ LL | move_out(x.f3_copy);
21
+ | ^^^^^^^^^ value used here after move
22
+
23
+ error[E0509]: cannot move out of type `U2`, which implements the `Drop` trait
24
+ --> $DIR/union-move.rs:49:18
25
+ |
26
+ LL | move_out(x.f1_nocopy);
27
+ | ^^^^^^^^^^^
28
+ | |
29
+ | cannot move out of here
30
+ | move occurs because `x.f1_nocopy` has type `RefCell<i32>`, which does not implement the `Copy` trait
31
+
32
+ error: aborting due to 3 previous errors
33
+
34
+ Some errors have detailed explanations: E0382, E0509.
35
+ For more information about an error, try `rustc --explain E0382`.
You can’t perform that action at this time.
0 commit comments