1
1
// run-pass
2
+ #![ feature( generators) ]
3
+ #![ feature( generator_trait) ]
2
4
use std:: cell:: Cell ;
3
5
use std:: mem;
6
+ use std:: ops:: Generator ;
7
+ use std:: pin:: Pin ;
4
8
5
9
struct Aligned < ' a > {
6
10
drop_count : & ' a Cell < usize >
@@ -19,15 +23,35 @@ impl<'a> Drop for Aligned<'a> {
19
23
}
20
24
}
21
25
26
+ #[ repr( transparent) ]
27
+ struct NotCopy ( u8 ) ;
28
+
22
29
#[ repr( packed) ]
23
- struct Packed < ' a > ( u8 , Aligned < ' a > ) ;
30
+ struct Packed < ' a > ( NotCopy , Aligned < ' a > ) ;
24
31
25
32
fn main ( ) {
26
33
let drop_count = & Cell :: new ( 0 ) ;
27
34
{
28
- let mut p = Packed ( 0 , Aligned { drop_count } ) ;
35
+ let mut p = Packed ( NotCopy ( 0 ) , Aligned { drop_count } ) ;
29
36
p. 1 = Aligned { drop_count } ;
30
37
assert_eq ! ( drop_count. get( ) , 1 ) ;
31
38
}
32
39
assert_eq ! ( drop_count. get( ) , 2 ) ;
40
+
41
+ let drop_count = & Cell :: new ( 0 ) ;
42
+ let mut g = || {
43
+ let mut p = Packed ( NotCopy ( 0 ) , Aligned { drop_count } ) ;
44
+ let _ = & p;
45
+ p. 1 = Aligned { drop_count } ;
46
+ assert_eq ! ( drop_count. get( ) , 1 ) ;
47
+ // Test that a generator drop function moves a value from a packed
48
+ // struct to a separate local before dropping it. We move out the
49
+ // first field to generate and open drop for the second field.
50
+ drop ( p. 0 ) ;
51
+ yield ;
52
+ } ;
53
+ Pin :: new ( & mut g) . resume ( ( ) ) ;
54
+ assert_eq ! ( drop_count. get( ) , 1 ) ;
55
+ drop ( g) ;
56
+ assert_eq ! ( drop_count. get( ) , 2 ) ;
33
57
}
0 commit comments