1
- //@ run-pass
1
+ //! Test that monomorphization correctly distinguishes types with different ABI alignment.
2
+ //!
3
+ //! On x86_64-linux-gnu and similar platforms, structs get 8-byte "preferred"
4
+ //! alignment, but their "ABI" alignment (what actually matters for data layout)
5
+ //! is the largest alignment of any field. If monomorphization incorrectly uses
6
+ //! "preferred" alignment instead of "ABI" alignment, it might unify types `A`
7
+ //! and `B` even though `S<A>` and `S<B>` have field `t` at different offsets,
8
+ //! leading to incorrect method dispatch for `unwrap()`.
2
9
3
- #![ allow( non_upper_case_globals) ]
4
- #![ allow( dead_code) ]
5
- /*!
6
- * On x86_64-linux-gnu and possibly other platforms, structs get 8-byte "preferred" alignment,
7
- * but their "ABI" alignment (i.e., what actually matters for data layout) is the largest alignment
8
- * of any field. (Also, `u64` has 8-byte ABI alignment; this is not always true).
9
- *
10
- * On such platforms, if monomorphize uses the "preferred" alignment, then it will unify
11
- * `A` and `B`, even though `S<A>` and `S<B>` have the field `t` at different offsets,
12
- * and apply the wrong instance of the method `unwrap`.
13
- */
10
+ //@ run-pass
14
11
15
12
#[ derive( Copy , Clone ) ]
16
- struct S < T > { i : u8 , t : T }
13
+ struct S < T > {
14
+ #[ allow( dead_code) ]
15
+ i : u8 ,
16
+ t : T ,
17
+ }
17
18
18
19
impl < T > S < T > {
19
20
fn unwrap ( self ) -> T {
@@ -22,14 +23,15 @@ impl<T> S<T> {
22
23
}
23
24
24
25
#[ derive( Copy , Clone , PartialEq , Debug ) ]
25
- struct A ( ( u32 , u32 ) ) ;
26
+ struct A ( ( u32 , u32 ) ) ; // Different ABI alignment than B
26
27
27
28
#[ derive( Copy , Clone , PartialEq , Debug ) ]
28
- struct B ( u64 ) ;
29
+ struct B ( u64 ) ; // Different ABI alignment than A
29
30
30
31
pub fn main ( ) {
31
- static Ca : S < A > = S { i : 0 , t : A ( ( 13 , 104 ) ) } ;
32
- static Cb : S < B > = S { i : 0 , t : B ( 31337 ) } ;
33
- assert_eq ! ( Ca . unwrap( ) , A ( ( 13 , 104 ) ) ) ;
34
- assert_eq ! ( Cb . unwrap( ) , B ( 31337 ) ) ;
32
+ static CA : S < A > = S { i : 0 , t : A ( ( 13 , 104 ) ) } ;
33
+ static CB : S < B > = S { i : 0 , t : B ( 31337 ) } ;
34
+
35
+ assert_eq ! ( CA . unwrap( ) , A ( ( 13 , 104 ) ) ) ;
36
+ assert_eq ! ( CB . unwrap( ) , B ( 31337 ) ) ;
35
37
}
0 commit comments