@@ -36,12 +36,14 @@ enum NicheBias {
3636}
3737
3838#[ derive( Copy , Clone , Debug ) ]
39- pub enum LayoutCalculatorError {
39+ pub enum LayoutCalculatorError < ' a , F > {
4040 /// An unsized type was found in a location where a sized type was expected.
4141 ///
4242 /// This is not always a compile error, for example if there is a `[T]: Sized`
4343 /// bound in a where clause.
44- UnexpectedUnsized ,
44+ ///
45+ /// Contains the field that was unexpectedly unsized.
46+ UnexpectedUnsized ( & ' a F ) ,
4547
4648 /// A type was too large for the target platform.
4749 SizeOverflow ,
@@ -50,8 +52,8 @@ pub enum LayoutCalculatorError {
5052 EmptyUnion ,
5153}
5254
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 > > ;
5557
5658#[ derive( Clone , Copy , Debug ) ]
5759pub struct LayoutCalculator < Cx > {
@@ -97,16 +99,17 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
9799 }
98100
99101 pub fn univariant <
100- ' a ,
102+ ' fields ,
103+ ' layout : ' fields ,
101104 FieldIdx : Idx ,
102105 VariantIdx : Idx ,
103- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
106+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
104107 > (
105108 & self ,
106- fields : & IndexSlice < FieldIdx , F > ,
109+ fields : & ' fields IndexSlice < FieldIdx , F > ,
107110 repr : & ReprOptions ,
108111 kind : StructKind ,
109- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
112+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
110113 let dl = self . cx . data_layout ( ) ;
111114 let layout = self . univariant_biased ( fields, repr, kind, NicheBias :: Start ) ;
112115 // 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> {
188191 }
189192
190193 pub fn layout_of_struct_or_enum <
191- ' a ,
194+ ' fields ,
195+ ' layout : ' fields ,
192196 FieldIdx : Idx ,
193197 VariantIdx : Idx ,
194- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
198+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
195199 > (
196200 & self ,
197201 repr : & ReprOptions ,
198- variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
202+ variants : & ' fields IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
199203 is_enum : bool ,
200204 is_unsafe_cell : bool ,
201205 scalar_valid_range : ( Bound < u128 > , Bound < u128 > ) ,
202206 discr_range_of_repr : impl Fn ( i128 , i128 ) -> ( Integer , bool ) ,
203207 discriminants : impl Iterator < Item = ( VariantIdx , i128 ) > ,
204208 dont_niche_optimize_enum : bool ,
205209 always_sized : bool ,
206- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
210+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
207211 let ( present_first, present_second) = {
208212 let mut present_variants = variants
209213 . iter_enumerated ( )
@@ -251,15 +255,16 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
251255 }
252256
253257 pub fn layout_of_union <
254- ' a ,
258+ ' fields ,
259+ ' layout : ' fields ,
255260 FieldIdx : Idx ,
256261 VariantIdx : Idx ,
257- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
262+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug + Clone ,
258263 > (
259264 & self ,
260265 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 > {
263268 let dl = self . cx . data_layout ( ) ;
264269 let mut align = if repr. pack . is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
265270 let mut max_repr_align = repr. align ;
@@ -279,7 +284,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
279284 let only_variant = & variants[ only_variant_idx] ;
280285 for field in only_variant {
281286 if field. is_unsized ( ) {
282- return Err ( LayoutCalculatorError :: UnexpectedUnsized ) ;
287+ return Err ( LayoutCalculatorError :: UnexpectedUnsized ( field ) ) ;
283288 }
284289
285290 align = align. max ( field. align ) ;
@@ -359,19 +364,22 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
359364 }
360365
361366 /// 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+ > (
363374 & self ,
364375 repr : & ReprOptions ,
365- variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
376+ variants : & ' fields IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
366377 is_enum : bool ,
367378 is_unsafe_cell : bool ,
368379 scalar_valid_range : ( Bound < u128 > , Bound < u128 > ) ,
369380 always_sized : bool ,
370381 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 > {
375383 // Struct, or univariant enum equivalent to a struct.
376384 // (Typechecking will reject discriminant-sizing attrs.)
377385
@@ -457,17 +465,20 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
457465 Ok ( st)
458466 }
459467
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+ > (
461475 & self ,
462476 repr : & ReprOptions ,
463- variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
477+ variants : & ' fields IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
464478 discr_range_of_repr : impl Fn ( i128 , i128 ) -> ( Integer , bool ) ,
465479 discriminants : impl Iterator < Item = ( VariantIdx , i128 ) > ,
466480 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 > {
471482 // Until we've decided whether to use the tagged or
472483 // niche filling LayoutS, we don't want to intern the
473484 // variant layouts, so we can't store them in the
@@ -969,17 +980,18 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
969980 }
970981
971982 fn univariant_biased <
972- ' a ,
983+ ' fields ,
984+ ' layout : ' fields ,
973985 FieldIdx : Idx ,
974986 VariantIdx : Idx ,
975- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
987+ F : Deref < Target = & ' layout LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
976988 > (
977989 & self ,
978- fields : & IndexSlice < FieldIdx , F > ,
990+ fields : & ' fields IndexSlice < FieldIdx , F > ,
979991 repr : & ReprOptions ,
980992 kind : StructKind ,
981993 niche_bias : NicheBias ,
982- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
994+ ) -> LayoutCalculatorResult < ' fields , FieldIdx , VariantIdx , F > {
983995 let dl = self . cx . data_layout ( ) ;
984996 let pack = repr. pack ;
985997 let mut align = if pack. is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
@@ -1124,7 +1136,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
11241136 // field 5 with offset 0 puts 0 in offsets[5].
11251137 // At the bottom of this function, we invert `inverse_memory_index` to
11261138 // produce `memory_index` (see `invert_mapping`).
1127- let mut sized = true ;
1139+ let mut unsized_field = None ;
11281140 let mut offsets = IndexVec :: from_elem ( Size :: ZERO , fields) ;
11291141 let mut offset = Size :: ZERO ;
11301142 let mut largest_niche = None ;
@@ -1137,12 +1149,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
11371149 }
11381150 for & i in & inverse_memory_index {
11391151 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 ) ) ;
11421154 }
11431155
11441156 if field. is_unsized ( ) {
1145- sized = false ;
1157+ unsized_field = Some ( field ) ;
11461158 }
11471159
11481160 // Invariant: offset < dl.obj_size_bound() <= 1<<61
@@ -1206,6 +1218,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
12061218 return Err ( LayoutCalculatorError :: SizeOverflow ) ;
12071219 }
12081220 let mut layout_of_single_non_zst_field = None ;
1221+ let sized = unsized_field. is_none ( ) ;
12091222 let mut abi = Abi :: Aggregate { sized } ;
12101223
12111224 let optimize_abi = !repr. inhibit_newtype_abi_optimization ( ) ;
0 commit comments