@@ -2,7 +2,10 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
2
2
use crate :: mir:: { GeneratorLayout , GeneratorSavedLocal } ;
3
3
use crate :: ty:: normalize_erasing_regions:: NormalizationError ;
4
4
use 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
+ } ;
6
9
use rustc_ast as ast;
7
10
use rustc_attr as attr;
8
11
use rustc_hir as hir;
@@ -221,114 +224,6 @@ impl<'tcx> fmt::Display for LayoutError<'tcx> {
221
224
}
222
225
}
223
226
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
-
332
227
#[ instrument( skip( tcx, query) , level = "debug" ) ]
333
228
fn layout_of < ' tcx > (
334
229
tcx : TyCtxt < ' tcx > ,
@@ -372,7 +267,7 @@ fn layout_of<'tcx>(
372
267
373
268
cx. record_layout_for_printing ( layout) ;
374
269
375
- sanity_check_layout ( tcx , param_env , & layout) ;
270
+ sanity_check_layout ( & cx , & layout) ;
376
271
377
272
Ok ( layout)
378
273
} )
0 commit comments