@@ -36,12 +36,14 @@ enum NicheBias {
3636}
3737
3838#[ derive( Copy , Clone , Debug ) ]
39- pub enum LayoutCalculatorError {
39+ pub enum LayoutCalculatorError < 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 ( 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 < FieldIdx , VariantIdx , F > =
56+ Result < LayoutS < FieldIdx , VariantIdx > , LayoutCalculatorError < F > > ;
5557
5658#[ derive( Clone , Copy , Debug ) ]
5759pub struct LayoutCalculator < Cx > {
@@ -100,13 +102,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
100102 ' a ,
101103 FieldIdx : Idx ,
102104 VariantIdx : Idx ,
103- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
105+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug + Copy ,
104106 > (
105107 & self ,
106108 fields : & IndexSlice < FieldIdx , F > ,
107109 repr : & ReprOptions ,
108110 kind : StructKind ,
109- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
111+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F > {
110112 let dl = self . cx . data_layout ( ) ;
111113 let layout = self . univariant_biased ( fields, repr, kind, NicheBias :: Start ) ;
112114 // Enums prefer niches close to the beginning or the end of the variants so that other
@@ -191,7 +193,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
191193 ' a ,
192194 FieldIdx : Idx ,
193195 VariantIdx : Idx ,
194- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
196+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug + Copy ,
195197 > (
196198 & self ,
197199 repr : & ReprOptions ,
@@ -203,7 +205,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
203205 discriminants : impl Iterator < Item = ( VariantIdx , i128 ) > ,
204206 dont_niche_optimize_enum : bool ,
205207 always_sized : bool ,
206- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
208+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F > {
207209 let ( present_first, present_second) = {
208210 let mut present_variants = variants
209211 . iter_enumerated ( )
@@ -254,12 +256,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
254256 ' a ,
255257 FieldIdx : Idx ,
256258 VariantIdx : Idx ,
257- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
259+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug + Copy ,
258260 > (
259261 & self ,
260262 repr : & ReprOptions ,
261263 variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
262- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
264+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F > {
263265 let dl = self . cx . data_layout ( ) ;
264266 let mut align = if repr. pack . is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
265267 let mut max_repr_align = repr. align ;
@@ -279,7 +281,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
279281 let only_variant = & variants[ only_variant_idx] ;
280282 for field in only_variant {
281283 if field. is_unsized ( ) {
282- return Err ( LayoutCalculatorError :: UnexpectedUnsized ) ;
284+ return Err ( LayoutCalculatorError :: UnexpectedUnsized ( * field ) ) ;
283285 }
284286
285287 align = align. max ( field. align ) ;
@@ -359,7 +361,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
359361 }
360362
361363 /// single-variant enums are just structs, if you think about it
362- fn layout_of_struct < ' a , FieldIdx : Idx , VariantIdx : Idx , F > (
364+ fn layout_of_struct <
365+ ' a ,
366+ FieldIdx : Idx ,
367+ VariantIdx : Idx ,
368+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug + Copy ,
369+ > (
363370 & self ,
364371 repr : & ReprOptions ,
365372 variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
@@ -368,10 +375,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
368375 scalar_valid_range : ( Bound < u128 > , Bound < u128 > ) ,
369376 always_sized : bool ,
370377 present_first : VariantIdx ,
371- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx >
372- where
373- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
374- {
378+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F > {
375379 // Struct, or univariant enum equivalent to a struct.
376380 // (Typechecking will reject discriminant-sizing attrs.)
377381
@@ -457,17 +461,19 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
457461 Ok ( st)
458462 }
459463
460- fn layout_of_enum < ' a , FieldIdx : Idx , VariantIdx : Idx , F > (
464+ fn layout_of_enum <
465+ ' a ,
466+ FieldIdx : Idx ,
467+ VariantIdx : Idx ,
468+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug + Copy ,
469+ > (
461470 & self ,
462471 repr : & ReprOptions ,
463472 variants : & IndexSlice < VariantIdx , IndexVec < FieldIdx , F > > ,
464473 discr_range_of_repr : impl Fn ( i128 , i128 ) -> ( Integer , bool ) ,
465474 discriminants : impl Iterator < Item = ( VariantIdx , i128 ) > ,
466475 dont_niche_optimize_enum : bool ,
467- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx >
468- where
469- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
470- {
476+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F > {
471477 // Until we've decided whether to use the tagged or
472478 // niche filling LayoutS, we don't want to intern the
473479 // variant layouts, so we can't store them in the
@@ -972,14 +978,14 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
972978 ' a ,
973979 FieldIdx : Idx ,
974980 VariantIdx : Idx ,
975- F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug ,
981+ F : Deref < Target = & ' a LayoutS < FieldIdx , VariantIdx > > + fmt:: Debug + Copy ,
976982 > (
977983 & self ,
978984 fields : & IndexSlice < FieldIdx , F > ,
979985 repr : & ReprOptions ,
980986 kind : StructKind ,
981987 niche_bias : NicheBias ,
982- ) -> LayoutCalculatorResult < FieldIdx , VariantIdx > {
988+ ) -> LayoutCalculatorResult < FieldIdx , VariantIdx , F > {
983989 let dl = self . cx . data_layout ( ) ;
984990 let pack = repr. pack ;
985991 let mut align = if pack. is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
@@ -1124,7 +1130,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
11241130 // field 5 with offset 0 puts 0 in offsets[5].
11251131 // At the bottom of this function, we invert `inverse_memory_index` to
11261132 // produce `memory_index` (see `invert_mapping`).
1127- let mut sized = true ;
1133+ let mut unsized_field = None :: < & F > ;
11281134 let mut offsets = IndexVec :: from_elem ( Size :: ZERO , fields) ;
11291135 let mut offset = Size :: ZERO ;
11301136 let mut largest_niche = None ;
@@ -1137,12 +1143,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
11371143 }
11381144 for & i in & inverse_memory_index {
11391145 let field = & fields[ i] ;
1140- if !sized {
1141- return Err ( LayoutCalculatorError :: UnexpectedUnsized ) ;
1146+ if let Some ( unsized_field ) = unsized_field {
1147+ return Err ( LayoutCalculatorError :: UnexpectedUnsized ( * unsized_field ) ) ;
11421148 }
11431149
11441150 if field. is_unsized ( ) {
1145- sized = false ;
1151+ unsized_field = Some ( field ) ;
11461152 }
11471153
11481154 // Invariant: offset < dl.obj_size_bound() <= 1<<61
@@ -1206,6 +1212,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
12061212 return Err ( LayoutCalculatorError :: SizeOverflow ) ;
12071213 }
12081214 let mut layout_of_single_non_zst_field = None ;
1215+ let sized = unsized_field. is_none ( ) ;
12091216 let mut abi = Abi :: Aggregate { sized } ;
12101217
12111218 let optimize_abi = !repr. inhibit_newtype_abi_optimization ( ) ;
0 commit comments