8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use std:: fmt;
12
+
11
13
#[ repr( C ) ]
12
14
enum CEnum {
13
15
Hello = 30 ,
14
16
World = 60
15
17
}
16
18
17
19
fn 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
+ }
24
26
}
25
27
26
28
#[ repr( packed) ]
27
- #[ derive( PartialEq , Debug ) ]
28
29
struct Pakd {
29
30
a : u64 ,
30
31
b : u32 ,
@@ -33,6 +34,36 @@ struct Pakd {
33
34
e : ( )
34
35
}
35
36
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
+
36
67
impl Drop for Pakd {
37
68
fn drop ( & mut self ) { }
38
69
}
@@ -59,12 +90,12 @@ fn test5(x: fn(u32) -> Option<u32>) -> (Option<u32>, Option<u32>) {
59
90
}
60
91
61
92
fn 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 ) ;
70
101
}
0 commit comments