@@ -98,6 +98,7 @@ fn struct_llfields<'a, 'tcx>(
9898 let mut offset = Size :: ZERO ;
9999 let mut prev_effective_align = layout. align . abi ;
100100 let mut result: Vec < _ > = Vec :: with_capacity ( 1 + field_count * 2 ) ;
101+ let mut projection = vec ! [ 0 ; field_count] ;
101102 for i in layout. fields . index_by_increasing_offset ( ) {
102103 let target_offset = layout. fields . offset ( i as usize ) ;
103104 let field = layout. field ( cx, i) ;
@@ -122,6 +123,7 @@ fn struct_llfields<'a, 'tcx>(
122123 result. push ( cx. type_padding_filler ( padding, padding_align) ) ;
123124 debug ! ( " padding before: {:?}" , padding) ;
124125 }
126+ projection[ i] = result. len ( ) as u32 ;
125127 result. push ( field. llvm_type ( cx) ) ;
126128 offset = target_offset + field. size ;
127129 prev_effective_align = effective_field_align;
@@ -143,6 +145,7 @@ fn struct_llfields<'a, 'tcx>(
143145 } else {
144146 debug ! ( "struct_llfields: offset: {:?} stride: {:?}" , offset, layout. size) ;
145147 }
148+ cx. field_projection_cache . borrow_mut ( ) . insert ( layout, projection) ;
146149
147150 ( result, packed)
148151}
@@ -356,24 +359,12 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
356359
357360 FieldsShape :: Array { .. } => index as u64 ,
358361
359- FieldsShape :: Arbitrary { .. } => {
360- let mut llvm_index = 0 ;
361- let mut offset = Size :: ZERO ;
362- for i in self . fields . index_by_increasing_offset ( ) {
363- let target_offset = self . fields . offset ( i as usize ) ;
364- let field = self . field ( cx, i) ;
365- let padding = target_offset - offset;
366- if padding != Size :: ZERO {
367- llvm_index += 1 ;
368- }
369- if i == index {
370- return llvm_index;
371- }
372- offset = target_offset + field. size ;
373- llvm_index += 1 ;
362+ FieldsShape :: Arbitrary { .. } => match cx. field_projection_cache . borrow ( ) . get ( self ) {
363+ Some ( projection) => projection[ index] as u64 ,
364+ None => {
365+ bug ! ( "TyAndLayout::llvm_field_index({:?}): field projection not cached" , self )
374366 }
375- bug ! ( "TyAndLayout::llvm_field_index({:?}): index {} out of range" , self , index)
376- }
367+ } ,
377368 }
378369 }
379370
0 commit comments