@@ -36,12 +36,14 @@ enum NicheBias {
36
36
}
37
37
38
38
#[ derive( Copy , Clone , Debug ) ]
39
- pub enum LayoutCalculatorError {
39
+ pub enum LayoutCalculatorError < ' a , F > {
40
40
/// An unsized type was found in a location where a sized type was expected.
41
41
///
42
42
/// This is not always a compile error, for example if there is a `[T]: Sized`
43
43
/// bound in a where clause.
44
- UnexpectedUnsized ,
44
+ ///
45
+ /// Contains the field that was unexpectedly unsized.
46
+ UnexpectedUnsized ( & ' a F ) ,
45
47
46
48
/// A type was too large for the target platform.
47
49
SizeOverflow ,
@@ -50,8 +52,8 @@ pub enum LayoutCalculatorError {
50
52
EmptyUnion ,
51
53
}
52
54
53
- type LayoutCalculatorResult < FieldIdx , VariantIdx > =
54
- Result < LayoutS < FieldIdx , VariantIdx > , LayoutCalculatorError > ;
55
+ type LayoutCalculatorResult < ' a , FieldIdx , VariantIdx , F > =
56
+ Result < LayoutS < FieldIdx , VariantIdx > , LayoutCalculatorError < ' a , F > > ;
55
57
56
58
#[ derive( Clone , Copy , Debug ) ]
57
59
pub struct LayoutCalculator < Cx > {
@@ -97,16 +99,17 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
97
99
}
98
100
99
101
pub fn univariant <
100
- ' a ,
102
+ ' fields ,
103
+ ' layout : ' fields ,
101
104
FieldIdx : Idx ,
102
105
VariantIdx : Idx ,
103
- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
106
+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
104
107
> (
105
108
& self ,
106
- fields : & IndexSlice < FieldIdx , F > ,
109
+ fields : & ' fields IndexSlice < FieldIdx , F > ,
107
110
repr : & ReprOptions ,
108
111
kind : StructKind ,
109
- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
112
+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
110
113
let dl = self . cx . data_layout ( ) ;
111
114
let layout = self . univariant_biased ( fields, repr, kind, NicheBias :: Start ) ;
112
115
// Enums prefer niches close to the beginning or the end of the variants so that other
@@ -188,22 +191,23 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
188
191
}
189
192
190
193
pub fn layout_of_struct_or_enum <
191
- ' a ,
194
+ ' fields ,
195
+ ' layout : ' fields ,
192
196
FieldIdx : Idx ,
193
197
VariantIdx : Idx ,
194
- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
198
+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
195
199
> (
196
200
& self ,
197
201
repr : & ReprOptions ,
198
- variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
202
+ variants : & ' fields IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
199
203
is_enum : bool ,
200
204
is_unsafe_cell : bool ,
201
205
scalar_valid_range : ( Bound < u128 > , Bound < u128 > ) ,
202
206
discr_range_of_repr : impl Fn ( i128 , i128 ) -> ( Integer , bool ) ,
203
207
discriminants : impl Iterator < Item = ( VariantIdx , i128 ) > ,
204
208
dont_niche_optimize_enum : bool ,
205
209
always_sized : bool ,
206
- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
210
+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
207
211
let ( present_first, present_second) = {
208
212
let mut present_variants = variants
209
213
. iter_enumerated ( )
@@ -251,15 +255,16 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
251
255
}
252
256
253
257
pub fn layout_of_union <
254
- ' a ,
258
+ ' fields ,
259
+ ' layout : ' fields ,
255
260
FieldIdx : Idx ,
256
261
VariantIdx : Idx ,
257
- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
262
+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug + Clone ,
258
263
> (
259
264
& self ,
260
265
repr : & ReprOptions ,
261
- variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
262
- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
266
+ variants : & ' fields IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
267
+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
263
268
let dl = self . cx . data_layout ( ) ;
264
269
let mut align = if repr. pack . is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
265
270
let mut max_repr_align = repr. align ;
@@ -279,7 +284,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
279
284
let only_variant = & variants[ only_variant_idx] ;
280
285
for field in only_variant {
281
286
if field. is_unsized ( ) {
282
- return Err ( LayoutCalculatorError :: UnexpectedUnsized ) ;
287
+ return Err ( LayoutCalculatorError :: UnexpectedUnsized ( field ) ) ;
283
288
}
284
289
285
290
align = align. max ( field. align ) ;
@@ -359,19 +364,22 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
359
364
}
360
365
361
366
/// single-variant enums are just structs, if you think about it
362
- fn layout_of_struct < ' a , FieldIdx : Idx , VariantIdx : Idx , F > (
367
+ fn layout_of_struct <
368
+ ' fields ,
369
+ ' layout : ' fields ,
370
+ FieldIdx : Idx ,
371
+ VariantIdx : Idx ,
372
+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
373
+ > (
363
374
& self ,
364
375
repr : & ReprOptions ,
365
- variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
376
+ variants : & ' fields IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
366
377
is_enum : bool ,
367
378
is_unsafe_cell : bool ,
368
379
scalar_valid_range : ( Bound < u128 > , Bound < u128 > ) ,
369
380
always_sized : bool ,
370
381
present_first : VariantIdx ,
371
- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx >
372
- where
373
- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
374
- {
382
+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
375
383
// Struct, or univariant enum equivalent to a struct.
376
384
// (Typechecking will reject discriminant-sizing attrs.)
377
385
@@ -457,17 +465,20 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
457
465
Ok ( st)
458
466
}
459
467
460
- fn layout_of_enum < ' a , FieldIdx : Idx , VariantIdx : Idx , F > (
468
+ fn layout_of_enum <
469
+ ' fields ,
470
+ ' layout : ' fields ,
471
+ FieldIdx : Idx ,
472
+ VariantIdx : Idx ,
473
+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
474
+ > (
461
475
& self ,
462
476
repr : & ReprOptions ,
463
- variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
477
+ variants : & ' fields IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
464
478
discr_range_of_repr : impl Fn ( i128 , i128 ) -> ( Integer , bool ) ,
465
479
discriminants : impl Iterator < Item = ( VariantIdx , i128 ) > ,
466
480
dont_niche_optimize_enum : bool ,
467
- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx >
468
- where
469
- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
470
- {
481
+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
471
482
// Until we've decided whether to use the tagged or
472
483
// niche filling LayoutS, we don't want to intern the
473
484
// variant layouts, so we can't store them in the
@@ -969,17 +980,18 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
969
980
}
970
981
971
982
fn univariant_biased <
972
- ' a ,
983
+ ' fields ,
984
+ ' layout : ' fields ,
973
985
FieldIdx : Idx ,
974
986
VariantIdx : Idx ,
975
- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
987
+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
976
988
> (
977
989
& self ,
978
- fields : & IndexSlice < FieldIdx , F > ,
990
+ fields : & ' fields IndexSlice < FieldIdx , F > ,
979
991
repr : & ReprOptions ,
980
992
kind : StructKind ,
981
993
niche_bias : NicheBias ,
982
- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
994
+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
983
995
let dl = self . cx . data_layout ( ) ;
984
996
let pack = repr. pack ;
985
997
let mut align = if pack. is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
@@ -1124,7 +1136,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1124
1136
// field 5 with offset 0 puts 0 in offsets[5].
1125
1137
// At the bottom of this function, we invert `inverse_memory_index` to
1126
1138
// produce `memory_index` (see `invert_mapping`).
1127
- let mut sized = true ;
1139
+ let mut unsized_field = None ;
1128
1140
let mut offsets = IndexVec :: from_elem ( Size :: ZERO , fields) ;
1129
1141
let mut offset = Size :: ZERO ;
1130
1142
let mut largest_niche = None ;
@@ -1137,12 +1149,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1137
1149
}
1138
1150
for & i in & inverse_memory_index {
1139
1151
let field = & fields[ i] ;
1140
- if !sized {
1141
- return Err ( LayoutCalculatorError :: UnexpectedUnsized ) ;
1152
+ if let Some ( unsized_field ) = unsized_field {
1153
+ return Err ( LayoutCalculatorError :: UnexpectedUnsized ( unsized_field ) ) ;
1142
1154
}
1143
1155
1144
1156
if field. is_unsized ( ) {
1145
- sized = false ;
1157
+ unsized_field = Some ( field ) ;
1146
1158
}
1147
1159
1148
1160
// Invariant: offset < dl.obj_size_bound() <= 1<<61
@@ -1206,6 +1218,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1206
1218
return Err ( LayoutCalculatorError :: SizeOverflow ) ;
1207
1219
}
1208
1220
let mut layout_of_single_non_zst_field = None ;
1221
+ let sized = unsized_field. is_none ( ) ;
1209
1222
let mut abi = Abi :: Aggregate { sized } ;
1210
1223
1211
1224
let optimize_abi = !repr. inhibit_newtype_abi_optimization ( ) ;
0 commit comments