@@ -151,14 +151,14 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
151151 | layout:: UntaggedUnion { .. } | layout:: RawNullablePointer { .. } => { }
152152 layout:: Univariant { ..}
153153 | layout:: StructWrappedNullablePointer { .. } => {
154- let ( nonnull_variant, packed) = match * l {
155- layout:: Univariant { ref variant, .. } => ( 0 , variant. packed ) ,
154+ let ( nonnull_variant_index , nonnull_variant, packed) = match * l {
155+ layout:: Univariant { ref variant, .. } => ( 0 , variant, variant . packed ) ,
156156 layout:: StructWrappedNullablePointer { nndiscr, ref nonnull, .. } =>
157- ( nndiscr, nonnull. packed ) ,
157+ ( nndiscr, nonnull, nonnull . packed ) ,
158158 _ => unreachable ! ( )
159159 } ;
160- let fields = compute_fields ( cx, t, nonnull_variant as usize , true ) ;
161- llty. set_struct_body ( & struct_llfields ( cx, & fields, false , false ) ,
160+ let fields = compute_fields ( cx, t, nonnull_variant_index as usize , true ) ;
161+ llty. set_struct_body ( & struct_llfields ( cx, & fields, nonnull_variant , false , false ) ,
162162 packed)
163163 } ,
164164 _ => bug ! ( "This function cannot handle {} with layout {:#?}" , t, l)
@@ -188,7 +188,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
188188 let fields = compute_fields ( cx, t, nndiscr as usize , false ) ;
189189 match name {
190190 None => {
191- Type :: struct_ ( cx, & struct_llfields ( cx, & fields, sizing, dst) ,
191+ Type :: struct_ ( cx, & struct_llfields ( cx, & fields, nonnull , sizing, dst) ,
192192 nonnull. packed )
193193 }
194194 Some ( name) => {
@@ -203,7 +203,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
203203 let fields = compute_fields ( cx, t, 0 , true ) ;
204204 match name {
205205 None => {
206- let fields = struct_llfields ( cx, & fields, sizing, dst) ;
206+ let fields = struct_llfields ( cx, & fields, & variant , sizing, dst) ;
207207 Type :: struct_ ( cx, & fields, variant. packed )
208208 }
209209 Some ( name) => {
@@ -291,12 +291,14 @@ fn union_fill(cx: &CrateContext, size: u64, align: u64) -> Type {
291291
292292
293293fn struct_llfields < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > , fields : & Vec < Ty < ' tcx > > ,
294+ variant : & layout:: Struct ,
294295 sizing : bool , dst : bool ) -> Vec < Type > {
296+ let fields = variant. field_index_by_increasing_offset ( ) . map ( |i| fields[ i as usize ] ) ;
295297 if sizing {
296- fields. iter ( ) . filter ( |& ty| !dst || type_is_sized ( cx. tcx ( ) , * ty) )
297- . map ( |& ty| type_of:: sizing_type_of ( cx, ty) ) . collect ( )
298+ fields. filter ( |ty| !dst || type_is_sized ( cx. tcx ( ) , * ty) )
299+ . map ( |ty| type_of:: sizing_type_of ( cx, ty) ) . collect ( )
298300 } else {
299- fields. iter ( ) . map ( |& ty| type_of:: in_memory_type_of ( cx, ty) ) . collect ( )
301+ fields. map ( |ty| type_of:: in_memory_type_of ( cx, ty) ) . collect ( )
300302 }
301303}
302304
@@ -564,16 +566,16 @@ pub fn trans_field_ptr_builder<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
564566fn struct_field_ptr < ' blk , ' tcx > ( bcx : & BlockAndBuilder < ' blk , ' tcx > ,
565567 st : & layout:: Struct , fields : & Vec < Ty < ' tcx > > , val : MaybeSizedValue ,
566568 ix : usize , needs_cast : bool ) -> ValueRef {
567- let ccx = bcx. ccx ( ) ;
568569 let fty = fields[ ix] ;
570+ let ccx = bcx. ccx ( ) ;
569571 let ll_fty = type_of:: in_memory_type_of ( bcx. ccx ( ) , fty) ;
570572 if bcx. is_unreachable ( ) {
571573 return C_undef ( ll_fty. ptr_to ( ) ) ;
572574 }
573575
574576 let ptr_val = if needs_cast {
575- let fields = fields . iter ( ) . map ( |& ty | {
576- type_of:: in_memory_type_of ( ccx, ty )
577+ let fields = st . field_index_by_increasing_offset ( ) . map ( |i | {
578+ type_of:: in_memory_type_of ( ccx, fields [ i ] )
577579 } ) . collect :: < Vec < _ > > ( ) ;
578580 let real_ty = Type :: struct_ ( ccx, & fields[ ..] , st. packed ) ;
579581 bcx. pointercast ( val. value , real_ty. ptr_to ( ) )
@@ -585,15 +587,15 @@ fn struct_field_ptr<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
585587 // * First field - Always aligned properly
586588 // * Packed struct - There is no alignment padding
587589 // * Field is sized - pointer is properly aligned already
588- if ix == 0 || st. packed || type_is_sized ( bcx. tcx ( ) , fty) {
589- return bcx. struct_gep ( ptr_val, ix ) ;
590+ if st . offsets [ ix ] == layout :: Size :: from_bytes ( 0 ) || st. packed || type_is_sized ( bcx. tcx ( ) , fty) {
591+ return bcx. struct_gep ( ptr_val, st . memory_index [ ix ] as usize ) ;
590592 }
591593
592594 // If the type of the last field is [T] or str, then we don't need to do
593595 // any adjusments
594596 match fty. sty {
595597 ty:: TySlice ( ..) | ty:: TyStr => {
596- return bcx. struct_gep ( ptr_val, ix ) ;
598+ return bcx. struct_gep ( ptr_val, st . memory_index [ ix ] as usize ) ;
597599 }
598600 _ => ( )
599601 }
@@ -755,8 +757,12 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
755757 // offset of current value
756758 let mut offset = 0 ;
757759 let mut cfields = Vec :: new ( ) ;
758- let offsets = st. offsets . iter ( ) . map ( |i| i. bytes ( ) ) ;
759- for ( & val, target_offset) in vals. iter ( ) . zip ( offsets) {
760+ cfields. reserve ( st. offsets . len ( ) * 2 ) ;
761+
762+ let parts = st. field_index_by_increasing_offset ( ) . map ( |i| {
763+ ( & vals[ i] , st. offsets [ i] . bytes ( ) )
764+ } ) ;
765+ for ( & val, target_offset) in parts {
760766 if offset < target_offset {
761767 cfields. push ( padding ( ccx, target_offset - offset) ) ;
762768 offset = target_offset;
@@ -807,14 +813,11 @@ pub fn const_get_field<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>,
807813 let l = ccx. layout_of ( t) ;
808814 match * l {
809815 layout:: CEnum { .. } => bug ! ( "element access in C-like enum const" ) ,
810- layout:: Univariant { .. } | layout:: Vector { .. } => const_struct_field ( val, ix) ,
816+ layout:: Univariant { ref variant, .. } => {
817+ const_struct_field ( val, variant. memory_index [ ix] as usize )
818+ }
819+ layout:: Vector { .. } => const_struct_field ( val, ix) ,
811820 layout:: UntaggedUnion { .. } => const_struct_field ( val, 0 ) ,
812- layout:: General { .. } => const_struct_field ( val, ix + 1 ) ,
813- layout:: RawNullablePointer { .. } => {
814- assert_eq ! ( ix, 0 ) ;
815- val
816- } ,
817- layout:: StructWrappedNullablePointer { .. } => const_struct_field ( val, ix) ,
818821 _ => bug ! ( "{} does not have fields." , t)
819822 }
820823}
0 commit comments