@@ -4,7 +4,7 @@ use rustc_middle::ty::{
44} ; 
55use  rustc_target:: abi:: * ; 
66
7- use  std:: cmp ; 
7+ use  std:: assert_matches :: assert_matches ; 
88
99/// Enforce some basic invariants on layouts. 
1010pub ( super )  fn  sanity_check_layout < ' tcx > ( 
@@ -68,21 +68,31 @@ pub(super) fn sanity_check_layout<'tcx>(
6868    } 
6969
7070    fn  check_layout_abi < ' tcx > ( cx :  & LayoutCx < ' tcx ,  TyCtxt < ' tcx > > ,  layout :  & TyAndLayout < ' tcx > )  { 
71+         // Verify the ABI mandated alignment and size. 
72+         let  align = layout. abi . inherent_align ( cx) . map ( |align| align. abi ) ; 
73+         let  size = layout. abi . inherent_size ( cx) ; 
74+         let  Some ( ( align,  size) )  = align. zip ( size)  else  { 
75+             assert_matches ! ( 
76+                 layout. layout. abi( ) , 
77+                 Abi :: Uninhabited  | Abi :: Aggregate  {  .. } , 
78+                 "ABI unexpectedly missing alignment and/or size in {layout:#?}" 
79+             ) ; 
80+             return 
81+         } ; 
82+         assert_eq ! ( 
83+             layout. layout. align( ) . abi, 
84+             align, 
85+             "alignment mismatch between ABI and layout in {layout:#?}" 
86+         ) ; 
87+         assert_eq ! ( 
88+             layout. layout. size( ) , 
89+             size, 
90+             "size mismatch between ABI and layout in {layout:#?}" 
91+         ) ; 
92+ 
93+         // Verify per-ABI invariants 
7194        match  layout. layout . abi ( )  { 
72-             Abi :: Scalar ( scalar)  => { 
73-                 // No padding in scalars. 
74-                 let  size = scalar. size ( cx) ; 
75-                 let  align = scalar. align ( cx) . abi ; 
76-                 assert_eq ! ( 
77-                     layout. layout. size( ) , 
78-                     size, 
79-                     "size mismatch between ABI and layout in {layout:#?}" 
80-                 ) ; 
81-                 assert_eq ! ( 
82-                     layout. layout. align( ) . abi, 
83-                     align, 
84-                     "alignment mismatch between ABI and layout in {layout:#?}" 
85-                 ) ; 
95+             Abi :: Scalar ( _)  => { 
8696                // Check that this matches the underlying field. 
8797                let  inner = skip_newtypes ( cx,  layout) ; 
8898                assert ! ( 
@@ -135,24 +145,6 @@ pub(super) fn sanity_check_layout<'tcx>(
135145                } 
136146            } 
137147            Abi :: ScalarPair ( scalar1,  scalar2)  => { 
138-                 // Sanity-check scalar pairs. Computing the expected size and alignment is a bit of work. 
139-                 let  size1 = scalar1. size ( cx) ; 
140-                 let  align1 = scalar1. align ( cx) . abi ; 
141-                 let  size2 = scalar2. size ( cx) ; 
142-                 let  align2 = scalar2. align ( cx) . abi ; 
143-                 let  align = cmp:: max ( align1,  align2) ; 
144-                 let  field2_offset = size1. align_to ( align2) ; 
145-                 let  size = ( field2_offset + size2) . align_to ( align) ; 
146-                 assert_eq ! ( 
147-                     layout. layout. size( ) , 
148-                     size, 
149-                     "size mismatch between ABI and layout in {layout:#?}" 
150-                 ) ; 
151-                 assert_eq ! ( 
152-                     layout. layout. align( ) . abi, 
153-                     align, 
154-                     "alignment mismatch between ABI and layout in {layout:#?}" , 
155-                 ) ; 
156148                // Check that the underlying pair of fields matches. 
157149                let  inner = skip_newtypes ( cx,  layout) ; 
158150                assert ! ( 
@@ -189,8 +181,9 @@ pub(super) fn sanity_check_layout<'tcx>(
189181                        "`ScalarPair` layout for type with less than two non-ZST fields: {inner:#?}" 
190182                    ) 
191183                } ) ; 
192-                 assert ! ( 
193-                     fields. next( ) . is_none( ) , 
184+                 assert_matches ! ( 
185+                     fields. next( ) , 
186+                     None , 
194187                    "`ScalarPair` layout for type with at least three non-ZST fields: {inner:#?}" 
195188                ) ; 
196189                // The fields might be in opposite order. 
@@ -200,6 +193,10 @@ pub(super) fn sanity_check_layout<'tcx>(
200193                    ( offset2,  field2,  offset1,  field1) 
201194                } ; 
202195                // The fields should be at the right offset, and match the `scalar` layout. 
196+                 let  size1 = scalar1. size ( cx) ; 
197+                 let  align1 = scalar1. align ( cx) . abi ; 
198+                 let  size2 = scalar2. size ( cx) ; 
199+                 let  align2 = scalar2. align ( cx) . abi ; 
203200                assert_eq ! ( 
204201                    offset1, 
205202                    Size :: ZERO , 
@@ -213,10 +210,12 @@ pub(super) fn sanity_check_layout<'tcx>(
213210                    field1. align. abi,  align1, 
214211                    "`ScalarPair` first field with bad align in {inner:#?}" , 
215212                ) ; 
216-                 assert ! ( 
217-                     matches!( field1. abi,  Abi :: Scalar ( _) ) , 
213+                 assert_matches ! ( 
214+                     field1. abi, 
215+                     Abi :: Scalar ( _) , 
218216                    "`ScalarPair` first field with bad ABI in {inner:#?}" , 
219217                ) ; 
218+                 let  field2_offset = size1. align_to ( align2) ; 
220219                assert_eq ! ( 
221220                    offset2,  field2_offset, 
222221                    "`ScalarPair` second field at bad offset in {inner:#?}" , 
@@ -229,27 +228,14 @@ pub(super) fn sanity_check_layout<'tcx>(
229228                    field2. align. abi,  align2, 
230229                    "`ScalarPair` second field with bad align in {inner:#?}" , 
231230                ) ; 
232-                 assert ! ( 
233-                     matches!( field2. abi,  Abi :: Scalar ( _) ) , 
231+                 assert_matches ! ( 
232+                     field2. abi, 
233+                     Abi :: Scalar ( _) , 
234234                    "`ScalarPair` second field with bad ABI in {inner:#?}" , 
235235                ) ; 
236236            } 
237-             Abi :: Vector  {  count,  element }  => { 
238-                 // No padding in vectors, except possibly for trailing padding to make the size a multiple of align. 
239-                 let  size = element. size ( cx)  *  count; 
240-                 let  align = cx. data_layout ( ) . vector_align ( size) . abi ; 
241-                 let  size = size. align_to ( align) ;  // needed e.g. for vectors of size 3 
237+             Abi :: Vector  {  element,  .. }  => { 
242238                assert ! ( align >= element. align( cx) . abi) ;  // just sanity-checking `vector_align`. 
243-                 assert_eq ! ( 
244-                     layout. layout. size( ) , 
245-                     size, 
246-                     "size mismatch between ABI and layout in {layout:#?}" 
247-                 ) ; 
248-                 assert_eq ! ( 
249-                     layout. layout. align( ) . abi, 
250-                     align, 
251-                     "alignment mismatch between ABI and layout in {layout:#?}" 
252-                 ) ; 
253239                // FIXME: Do some kind of check of the inner type, like for Scalar and ScalarPair. 
254240            } 
255241            Abi :: Uninhabited  | Abi :: Aggregate  {  .. }  => { }  // Nothing to check. 
0 commit comments