@@ -31,7 +31,7 @@ pub fn provide(providers: &mut Providers) {
31
31
fn layout_of < ' tcx > (
32
32
tcx : TyCtxt < ' tcx > ,
33
33
query : ty:: ParamEnvAnd < ' tcx , Ty < ' tcx > > ,
34
- ) -> Result < TyAndLayout < ' tcx > , LayoutError < ' tcx > > {
34
+ ) -> Result < TyAndLayout < ' tcx > , & ' tcx LayoutError < ' tcx > > {
35
35
let ( param_env, ty) = query. into_parts ( ) ;
36
36
debug ! ( ?ty) ;
37
37
@@ -45,7 +45,9 @@ fn layout_of<'tcx>(
45
45
let ty = match tcx. try_normalize_erasing_regions ( param_env, ty) {
46
46
Ok ( t) => t,
47
47
Err ( normalization_error) => {
48
- return Err ( LayoutError :: NormalizationFailure ( ty, normalization_error) ) ;
48
+ return Err ( tcx
49
+ . arena
50
+ . alloc ( LayoutError :: NormalizationFailure ( ty, normalization_error) ) ) ;
49
51
}
50
52
} ;
51
53
@@ -66,27 +68,34 @@ fn layout_of<'tcx>(
66
68
Ok ( layout)
67
69
}
68
70
71
+ fn error < ' tcx > (
72
+ cx : & LayoutCx < ' tcx , TyCtxt < ' tcx > > ,
73
+ err : LayoutError < ' tcx > ,
74
+ ) -> & ' tcx LayoutError < ' tcx > {
75
+ cx. tcx . arena . alloc ( err)
76
+ }
77
+
69
78
fn univariant_uninterned < ' tcx > (
70
79
cx : & LayoutCx < ' tcx , TyCtxt < ' tcx > > ,
71
80
ty : Ty < ' tcx > ,
72
81
fields : & IndexSlice < FieldIdx , Layout < ' _ > > ,
73
82
repr : & ReprOptions ,
74
83
kind : StructKind ,
75
- ) -> Result < LayoutS , LayoutError < ' tcx > > {
84
+ ) -> Result < LayoutS , & ' tcx LayoutError < ' tcx > > {
76
85
let dl = cx. data_layout ( ) ;
77
86
let pack = repr. pack ;
78
87
if pack. is_some ( ) && repr. align . is_some ( ) {
79
88
cx. tcx . sess . delay_span_bug ( DUMMY_SP , "struct cannot be packed and aligned" ) ;
80
- return Err ( LayoutError :: Unknown ( ty) ) ;
89
+ return Err ( cx . tcx . arena . alloc ( LayoutError :: Unknown ( ty) ) ) ;
81
90
}
82
91
83
- cx. univariant ( dl, fields, repr, kind) . ok_or ( LayoutError :: SizeOverflow ( ty) )
92
+ cx. univariant ( dl, fields, repr, kind) . ok_or_else ( || error ( cx , LayoutError :: SizeOverflow ( ty) ) )
84
93
}
85
94
86
95
fn layout_of_uncached < ' tcx > (
87
96
cx : & LayoutCx < ' tcx , TyCtxt < ' tcx > > ,
88
97
ty : Ty < ' tcx > ,
89
- ) -> Result < Layout < ' tcx > , LayoutError < ' tcx > > {
98
+ ) -> Result < Layout < ' tcx > , & ' tcx LayoutError < ' tcx > > {
90
99
let tcx = cx. tcx ;
91
100
let param_env = cx. param_env ;
92
101
let dl = cx. data_layout ( ) ;
@@ -170,7 +179,7 @@ fn layout_of_uncached<'tcx>(
170
179
err = better_err;
171
180
}
172
181
}
173
- return Err ( LayoutError :: NormalizationFailure ( pointee, err) ) ;
182
+ return Err ( error ( cx , LayoutError :: NormalizationFailure ( pointee, err) ) ) ;
174
183
} ,
175
184
} ;
176
185
@@ -181,7 +190,7 @@ fn layout_of_uncached<'tcx>(
181
190
}
182
191
183
192
let Abi :: Scalar ( metadata) = metadata_layout. abi else {
184
- return Err ( LayoutError :: Unknown ( pointee) ) ;
193
+ return Err ( error ( cx , LayoutError :: Unknown ( pointee) ) ) ;
185
194
} ;
186
195
187
196
metadata
@@ -199,7 +208,7 @@ fn layout_of_uncached<'tcx>(
199
208
vtable
200
209
}
201
210
_ => {
202
- return Err ( LayoutError :: Unknown ( pointee) ) ;
211
+ return Err ( error ( cx , LayoutError :: Unknown ( pointee) ) ) ;
203
212
}
204
213
}
205
214
} ;
@@ -221,14 +230,18 @@ fn layout_of_uncached<'tcx>(
221
230
if count. has_projections ( ) {
222
231
count = tcx. normalize_erasing_regions ( param_env, count) ;
223
232
if count. has_projections ( ) {
224
- return Err ( LayoutError :: Unknown ( ty) ) ;
233
+ return Err ( error ( cx , LayoutError :: Unknown ( ty) ) ) ;
225
234
}
226
235
}
227
236
228
- let count =
229
- count. try_eval_target_usize ( tcx, param_env) . ok_or ( LayoutError :: Unknown ( ty) ) ?;
237
+ let count = count
238
+ . try_eval_target_usize ( tcx, param_env)
239
+ . ok_or_else ( || error ( cx, LayoutError :: Unknown ( ty) ) ) ?;
230
240
let element = cx. layout_of ( element) ?;
231
- let size = element. size . checked_mul ( count, dl) . ok_or ( LayoutError :: SizeOverflow ( ty) ) ?;
241
+ let size = element
242
+ . size
243
+ . checked_mul ( count, dl)
244
+ . ok_or_else ( || error ( cx, LayoutError :: SizeOverflow ( ty) ) ) ?;
232
245
233
246
let abi = if count != 0 && ty. is_privately_uninhabited ( tcx, param_env) {
234
247
Abi :: Uninhabited
@@ -316,7 +329,7 @@ fn layout_of_uncached<'tcx>(
316
329
DUMMY_SP ,
317
330
"#[repr(simd)] was applied to an ADT that is not a struct" ,
318
331
) ;
319
- return Err ( LayoutError :: Unknown ( ty) ) ;
332
+ return Err ( error ( cx , LayoutError :: Unknown ( ty) ) ) ;
320
333
}
321
334
322
335
let fields = & def. non_enum_variant ( ) . fields ;
@@ -346,7 +359,7 @@ fn layout_of_uncached<'tcx>(
346
359
DUMMY_SP ,
347
360
"#[repr(simd)] was applied to an ADT with heterogeneous field type" ,
348
361
) ;
349
- return Err ( LayoutError :: Unknown ( ty) ) ;
362
+ return Err ( error ( cx , LayoutError :: Unknown ( ty) ) ) ;
350
363
}
351
364
}
352
365
@@ -368,7 +381,7 @@ fn layout_of_uncached<'tcx>(
368
381
369
382
// Extract the number of elements from the layout of the array field:
370
383
let FieldsShape :: Array { count, .. } = cx. layout_of ( f0_ty) ?. layout . fields ( ) else {
371
- return Err ( LayoutError :: Unknown ( ty) ) ;
384
+ return Err ( error ( cx , LayoutError :: Unknown ( ty) ) ) ;
372
385
} ;
373
386
374
387
( * e_ty, * count, true )
@@ -397,7 +410,10 @@ fn layout_of_uncached<'tcx>(
397
410
} ;
398
411
399
412
// Compute the size and alignment of the vector:
400
- let size = e_ly. size . checked_mul ( e_len, dl) . ok_or ( LayoutError :: SizeOverflow ( ty) ) ?;
413
+ let size = e_ly
414
+ . size
415
+ . checked_mul ( e_len, dl)
416
+ . ok_or_else ( || error ( cx, LayoutError :: SizeOverflow ( ty) ) ) ?;
401
417
let align = dl. vector_align ( size) ;
402
418
let size = size. align_to ( align. abi ) ;
403
419
@@ -438,11 +454,12 @@ fn layout_of_uncached<'tcx>(
438
454
tcx. def_span ( def. did ( ) ) ,
439
455
"union cannot be packed and aligned" ,
440
456
) ;
441
- return Err ( LayoutError :: Unknown ( ty) ) ;
457
+ return Err ( error ( cx , LayoutError :: Unknown ( ty) ) ) ;
442
458
}
443
459
444
460
return Ok ( tcx. mk_layout (
445
- cx. layout_of_union ( & def. repr ( ) , & variants) . ok_or ( LayoutError :: Unknown ( ty) ) ?,
461
+ cx. layout_of_union ( & def. repr ( ) , & variants)
462
+ . ok_or_else ( || error ( cx, LayoutError :: Unknown ( ty) ) ) ?,
446
463
) ) ;
447
464
}
448
465
@@ -476,23 +493,23 @@ fn layout_of_uncached<'tcx>(
476
493
}
477
494
} ,
478
495
)
479
- . ok_or ( LayoutError :: SizeOverflow ( ty) ) ?,
496
+ . ok_or_else ( || error ( cx , LayoutError :: SizeOverflow ( ty) ) ) ?,
480
497
)
481
498
}
482
499
483
500
// Types with no meaningful known layout.
484
501
ty:: Alias ( ..) => {
485
502
// NOTE(eddyb) `layout_of` query should've normalized these away,
486
503
// if that was possible, so there's no reason to try again here.
487
- return Err ( LayoutError :: Unknown ( ty) ) ;
504
+ return Err ( error ( cx , LayoutError :: Unknown ( ty) ) ) ;
488
505
}
489
506
490
507
ty:: Bound ( ..) | ty:: GeneratorWitness ( ..) | ty:: GeneratorWitnessMIR ( ..) | ty:: Infer ( _) => {
491
508
bug ! ( "Layout::compute: unexpected type `{}`" , ty)
492
509
}
493
510
494
511
ty:: Placeholder ( ..) | ty:: Param ( _) | ty:: Error ( _) => {
495
- return Err ( LayoutError :: Unknown ( ty) ) ;
512
+ return Err ( error ( cx , LayoutError :: Unknown ( ty) ) ) ;
496
513
}
497
514
} )
498
515
}
@@ -628,13 +645,13 @@ fn generator_layout<'tcx>(
628
645
ty : Ty < ' tcx > ,
629
646
def_id : hir:: def_id:: DefId ,
630
647
substs : SubstsRef < ' tcx > ,
631
- ) -> Result < Layout < ' tcx > , LayoutError < ' tcx > > {
648
+ ) -> Result < Layout < ' tcx > , & ' tcx LayoutError < ' tcx > > {
632
649
use SavedLocalEligibility :: * ;
633
650
let tcx = cx. tcx ;
634
651
let subst_field = |ty : Ty < ' tcx > | EarlyBinder :: bind ( ty) . subst ( tcx, substs) ;
635
652
636
653
let Some ( info) = tcx. generator_layout ( def_id) else {
637
- return Err ( LayoutError :: Unknown ( ty) ) ;
654
+ return Err ( error ( cx , LayoutError :: Unknown ( ty) ) ) ;
638
655
} ;
639
656
let ( ineligible_locals, assignments) = generator_saved_local_eligibility ( & info) ;
640
657
0 commit comments