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()`.
29
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
1411
1512#[ 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+ }
1718
1819impl < T > S < T > {
1920 fn unwrap ( self ) -> T {
@@ -22,14 +23,15 @@ impl<T> S<T> {
2223}
2324
2425#[ derive( Copy , Clone , PartialEq , Debug ) ]
25- struct A ( ( u32 , u32 ) ) ;
26+ struct A ( ( u32 , u32 ) ) ; // Different ABI alignment than B
2627
2728#[ derive( Copy , Clone , PartialEq , Debug ) ]
28- struct B ( u64 ) ;
29+ struct B ( u64 ) ; // Different ABI alignment than A
2930
3031pub 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 ) ) ;
3537}
0 commit comments