@@ -151,14 +151,14 @@ pub fn finish_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
151
151
| layout:: UntaggedUnion { .. } | layout:: RawNullablePointer { .. } => { }
152
152
layout:: Univariant { ..}
153
153
| 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 ) ,
156
156
layout:: StructWrappedNullablePointer { nndiscr, ref nonnull, .. } =>
157
- ( nndiscr, nonnull. packed ) ,
157
+ ( nndiscr, nonnull, nonnull . packed ) ,
158
158
_ => unreachable ! ( )
159
159
} ;
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 ) ,
162
162
packed)
163
163
} ,
164
164
_ => bug ! ( "This function cannot handle {} with layout {:#?}" , t, l)
@@ -188,7 +188,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
188
188
let fields = compute_fields ( cx, t, nndiscr as usize , false ) ;
189
189
match name {
190
190
None => {
191
- Type :: struct_ ( cx, & struct_llfields ( cx, & fields, sizing, dst) ,
191
+ Type :: struct_ ( cx, & struct_llfields ( cx, & fields, nonnull , sizing, dst) ,
192
192
nonnull. packed )
193
193
}
194
194
Some ( name) => {
@@ -203,7 +203,7 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
203
203
let fields = compute_fields ( cx, t, 0 , true ) ;
204
204
match name {
205
205
None => {
206
- let fields = struct_llfields ( cx, & fields, sizing, dst) ;
206
+ let fields = struct_llfields ( cx, & fields, & variant , sizing, dst) ;
207
207
Type :: struct_ ( cx, & fields, variant. packed )
208
208
}
209
209
Some ( name) => {
@@ -291,12 +291,14 @@ fn union_fill(cx: &CrateContext, size: u64, align: u64) -> Type {
291
291
292
292
293
293
fn struct_llfields < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > , fields : & Vec < Ty < ' tcx > > ,
294
+ variant : & layout:: Struct ,
294
295
sizing : bool , dst : bool ) -> Vec < Type > {
296
+ let fields = variant. field_index_by_increasing_offset ( ) . map ( |i| fields[ i as usize ] ) ;
295
297
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 ( )
298
300
} 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 ( )
300
302
}
301
303
}
302
304
@@ -564,16 +566,16 @@ pub fn trans_field_ptr_builder<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
564
566
fn struct_field_ptr < ' blk , ' tcx > ( bcx : & BlockAndBuilder < ' blk , ' tcx > ,
565
567
st : & layout:: Struct , fields : & Vec < Ty < ' tcx > > , val : MaybeSizedValue ,
566
568
ix : usize , needs_cast : bool ) -> ValueRef {
567
- let ccx = bcx. ccx ( ) ;
568
569
let fty = fields[ ix] ;
570
+ let ccx = bcx. ccx ( ) ;
569
571
let ll_fty = type_of:: in_memory_type_of ( bcx. ccx ( ) , fty) ;
570
572
if bcx. is_unreachable ( ) {
571
573
return C_undef ( ll_fty. ptr_to ( ) ) ;
572
574
}
573
575
574
576
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 ] )
577
579
} ) . collect :: < Vec < _ > > ( ) ;
578
580
let real_ty = Type :: struct_ ( ccx, & fields[ ..] , st. packed ) ;
579
581
bcx. pointercast ( val. value , real_ty. ptr_to ( ) )
@@ -585,15 +587,15 @@ fn struct_field_ptr<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
585
587
// * First field - Always aligned properly
586
588
// * Packed struct - There is no alignment padding
587
589
// * 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 ) ;
590
592
}
591
593
592
594
// If the type of the last field is [T] or str, then we don't need to do
593
595
// any adjusments
594
596
match fty. sty {
595
597
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 ) ;
597
599
}
598
600
_ => ( )
599
601
}
@@ -755,8 +757,12 @@ fn build_const_struct<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
755
757
// offset of current value
756
758
let mut offset = 0 ;
757
759
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 {
760
766
if offset < target_offset {
761
767
cfields. push ( padding ( ccx, target_offset - offset) ) ;
762
768
offset = target_offset;
@@ -807,14 +813,11 @@ pub fn const_get_field<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>,
807
813
let l = ccx. layout_of ( t) ;
808
814
match * l {
809
815
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) ,
811
820
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) ,
818
821
_ => bug ! ( "{} does not have fields." , t)
819
822
}
820
823
}
0 commit comments