11// run-pass
2+ #![ feature( generators) ]
3+ #![ feature( generator_trait) ]
24use std:: cell:: Cell ;
35use std:: mem;
6+ use std:: ops:: Generator ;
7+ use std:: pin:: Pin ;
48
59struct Aligned < ' a > {
610 drop_count : & ' a Cell < usize >
@@ -19,15 +23,35 @@ impl<'a> Drop for Aligned<'a> {
1923 }
2024}
2125
26+ #[ repr( transparent) ]
27+ struct NotCopy ( u8 ) ;
28+
2229#[ repr( packed) ]
23- struct Packed < ' a > ( u8 , Aligned < ' a > ) ;
30+ struct Packed < ' a > ( NotCopy , Aligned < ' a > ) ;
2431
2532fn main ( ) {
2633 let drop_count = & Cell :: new ( 0 ) ;
2734 {
28- let mut p = Packed ( 0 , Aligned { drop_count } ) ;
35+ let mut p = Packed ( NotCopy ( 0 ) , Aligned { drop_count } ) ;
2936 p. 1 = Aligned { drop_count } ;
3037 assert_eq ! ( drop_count. get( ) , 1 ) ;
3138 }
3239 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 ) ;
3357}
0 commit comments