@@ -2,7 +2,10 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
22use crate :: mir:: { GeneratorLayout , GeneratorSavedLocal } ;
33use crate :: ty:: normalize_erasing_regions:: NormalizationError ;
44use crate :: ty:: subst:: Subst ;
5- use crate :: ty:: { self , subst:: SubstsRef , EarlyBinder , ReprOptions , Ty , TyCtxt , TypeVisitable } ;
5+ use crate :: ty:: {
6+ self , layout_sanity_check:: sanity_check_layout, subst:: SubstsRef , EarlyBinder , ReprOptions , Ty ,
7+ TyCtxt , TypeVisitable ,
8+ } ;
69use rustc_ast as ast;
710use rustc_attr as attr;
811use rustc_hir as hir;
@@ -221,114 +224,6 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
221224 }
222225}
223226
224- /// Enforce some basic invariants on layouts.
225- fn sanity_check_layout < ' tcx > (
226- tcx : TyCtxt < ' tcx > ,
227- param_env : ty:: ParamEnv < ' tcx > ,
228- layout : & TyAndLayout < ' tcx > ,
229- ) {
230- // Type-level uninhabitedness should always imply ABI uninhabitedness.
231- if tcx. conservative_is_privately_uninhabited ( param_env. and ( layout. ty ) ) {
232- assert ! ( layout. abi. is_uninhabited( ) ) ;
233- }
234-
235- if layout. size . bytes ( ) % layout. align . abi . bytes ( ) != 0 {
236- bug ! ( "size is not a multiple of align, in the following layout:\n {layout:#?}" ) ;
237- }
238-
239- if cfg ! ( debug_assertions) {
240- fn check_layout_abi < ' tcx > ( tcx : TyCtxt < ' tcx > , layout : Layout < ' tcx > ) {
241- match layout. abi ( ) {
242- Abi :: Scalar ( scalar) => {
243- // No padding in scalars.
244- assert_eq ! (
245- layout. align( ) . abi,
246- scalar. align( & tcx) . abi,
247- "alignment mismatch between ABI and layout in {layout:#?}"
248- ) ;
249- assert_eq ! (
250- layout. size( ) ,
251- scalar. size( & tcx) ,
252- "size mismatch between ABI and layout in {layout:#?}"
253- ) ;
254- }
255- Abi :: Vector { count, element } => {
256- // No padding in vectors. Alignment can be strengthened, though.
257- assert ! (
258- layout. align( ) . abi >= element. align( & tcx) . abi,
259- "alignment mismatch between ABI and layout in {layout:#?}"
260- ) ;
261- let size = element. size ( & tcx) * count;
262- assert_eq ! (
263- layout. size( ) ,
264- size. align_to( tcx. data_layout( ) . vector_align( size) . abi) ,
265- "size mismatch between ABI and layout in {layout:#?}"
266- ) ;
267- }
268- Abi :: ScalarPair ( scalar1, scalar2) => {
269- // Sanity-check scalar pairs. These are a bit more flexible and support
270- // padding, but we can at least ensure both fields actually fit into the layout
271- // and the alignment requirement has not been weakened.
272- let align1 = scalar1. align ( & tcx) . abi ;
273- let align2 = scalar2. align ( & tcx) . abi ;
274- assert ! (
275- layout. align( ) . abi >= cmp:: max( align1, align2) ,
276- "alignment mismatch between ABI and layout in {layout:#?}" ,
277- ) ;
278- let field2_offset = scalar1. size ( & tcx) . align_to ( align2) ;
279- assert ! (
280- layout. size( ) >= field2_offset + scalar2. size( & tcx) ,
281- "size mismatch between ABI and layout in {layout:#?}"
282- ) ;
283- }
284- Abi :: Uninhabited | Abi :: Aggregate { .. } => { } // Nothing to check.
285- }
286- }
287-
288- check_layout_abi ( tcx, layout. layout ) ;
289-
290- if let Variants :: Multiple { variants, .. } = & layout. variants {
291- for variant in variants {
292- check_layout_abi ( tcx, * variant) ;
293- // No nested "multiple".
294- assert ! ( matches!( variant. variants( ) , Variants :: Single { .. } ) ) ;
295- // Skip empty variants.
296- if variant. size ( ) == Size :: ZERO
297- || variant. fields ( ) . count ( ) == 0
298- || variant. abi ( ) . is_uninhabited ( )
299- {
300- // These are never actually accessed anyway, so we can skip them. (Note that
301- // sometimes, variants with fields have size 0, and sometimes, variants without
302- // fields have non-0 size.)
303- continue ;
304- }
305- // Variants should have the same or a smaller size as the full thing.
306- if variant. size ( ) > layout. size {
307- bug ! (
308- "Type with size {} bytes has variant with size {} bytes: {layout:#?}" ,
309- layout. size. bytes( ) ,
310- variant. size( ) . bytes( ) ,
311- )
312- }
313- // The top-level ABI and the ABI of the variants should be coherent.
314- let abi_coherent = match ( layout. abi , variant. abi ( ) ) {
315- ( Abi :: Scalar ( ..) , Abi :: Scalar ( ..) ) => true ,
316- ( Abi :: ScalarPair ( ..) , Abi :: ScalarPair ( ..) ) => true ,
317- ( Abi :: Uninhabited , _) => true ,
318- ( Abi :: Aggregate { .. } , _) => true ,
319- _ => false ,
320- } ;
321- if !abi_coherent {
322- bug ! (
323- "Variant ABI is incompatible with top-level ABI:\n variant={:#?}\n Top-level: {layout:#?}" ,
324- variant
325- ) ;
326- }
327- }
328- }
329- }
330- }
331-
332227#[ instrument( skip( tcx, query) , level = "debug" ) ]
333228fn layout_of < ' tcx > (
334229 tcx : TyCtxt < ' tcx > ,
@@ -372,7 +267,7 @@ fn layout_of<'tcx>(
372267
373268 cx. record_layout_for_printing ( layout) ;
374269
375- sanity_check_layout ( tcx , param_env , & layout) ;
270+ sanity_check_layout ( & cx , & layout) ;
376271
377272 Ok ( layout)
378273 } )
0 commit comments