88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11+ use std:: fmt;
12+
1113#[ repr( C ) ]
1214enum CEnum {
1315 Hello = 30 ,
1416 World = 60
1517}
1618
1719fn test1 ( c : CEnum ) -> i32 {
18- let c2 = CEnum :: Hello ;
19- match ( c, c2) {
20- ( CEnum :: Hello , CEnum :: Hello ) => 42 ,
21- ( CEnum :: World , CEnum :: Hello ) => 0 ,
22- _ => 1
23- }
20+ let c2 = CEnum :: Hello ;
21+ match ( c, c2) {
22+ ( CEnum :: Hello , CEnum :: Hello ) => 42 ,
23+ ( CEnum :: World , CEnum :: Hello ) => 0 ,
24+ _ => 1
25+ }
2426}
2527
2628#[ repr( packed) ]
27- #[ derive( PartialEq , Debug ) ]
2829struct Pakd {
2930 a : u64 ,
3031 b : u32 ,
@@ -33,6 +34,36 @@ struct Pakd {
3334 e : ( )
3435}
3536
37+ // It is unsafe to use #[derive(Debug)] on a packed struct because the code generated by the derive
38+ // macro takes references to the fields instead of accessing them directly.
39+ impl fmt:: Debug for Pakd {
40+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
41+ // It's important that we load the fields into locals by-value here. This will do safe
42+ // unaligned loads into the locals, then pass references to the properly-aligned locals to
43+ // the formatting code.
44+ let Pakd { a, b, c, d, e } = * self ;
45+ f. debug_struct ( "Pakd" )
46+ . field ( "a" , & a)
47+ . field ( "b" , & b)
48+ . field ( "c" , & c)
49+ . field ( "d" , & d)
50+ . field ( "e" , & e)
51+ . finish ( )
52+ }
53+ }
54+
55+ // It is unsafe to use #[derive(PartialEq)] on a packed struct because the code generated by the
56+ // derive macro takes references to the fields instead of accessing them directly.
57+ impl PartialEq for Pakd {
58+ fn eq ( & self , other : & Pakd ) -> bool {
59+ self . a == other. a &&
60+ self . b == other. b &&
61+ self . c == other. c &&
62+ self . d == other. d &&
63+ self . e == other. e
64+ }
65+ }
66+
3667impl Drop for Pakd {
3768 fn drop ( & mut self ) { }
3869}
@@ -59,12 +90,12 @@ fn test5(x: fn(u32) -> Option<u32>) -> (Option<u32>, Option<u32>) {
5990}
6091
6192fn main ( ) {
62- assert_eq ! ( test1( CEnum :: Hello ) , 42 ) ;
63- assert_eq ! ( test1( CEnum :: World ) , 0 ) ;
64- assert_eq ! ( test2( ) , Pakd { a: 42 , b: 42 , c: 42 , d: 42 , e: ( ) } ) ;
65- assert_eq ! ( test3( ) , TupleLike ( 42 , 42 ) ) ;
66- let t4 = test4 ( TupleLike ) ;
67- assert_eq ! ( t4. 0 , t4. 1 ) ;
68- let t5 = test5 ( Some ) ;
69- assert_eq ! ( t5. 0 , t5. 1 ) ;
93+ assert_eq ! ( test1( CEnum :: Hello ) , 42 ) ;
94+ assert_eq ! ( test1( CEnum :: World ) , 0 ) ;
95+ assert_eq ! ( test2( ) , Pakd { a: 42 , b: 42 , c: 42 , d: 42 , e: ( ) } ) ;
96+ assert_eq ! ( test3( ) , TupleLike ( 42 , 42 ) ) ;
97+ let t4 = test4 ( TupleLike ) ;
98+ assert_eq ! ( t4. 0 , t4. 1 ) ;
99+ let t5 = test5 ( Some ) ;
100+ assert_eq ! ( t5. 0 , t5. 1 ) ;
70101}
0 commit comments