@@ -717,16 +717,18 @@ impl<'a, 'gcx, 'tcx> Struct {
717717
718718 /// Find the path leading to a non-zero leaf field, starting from
719719 /// the given type and recursing through aggregates.
720+ /// The tuple is `(path, source_path)1,
721+ /// where `path` is in memory order and `source_path` in source order.
720722 // FIXME(eddyb) track value ranges and traverse already optimized enums.
721723 fn non_zero_field_in_type ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
722724 ty : Ty < ' gcx > )
723- -> Result < Option < FieldPath > , LayoutError < ' gcx > > {
725+ -> Result < Option < ( FieldPath , FieldPath ) > , LayoutError < ' gcx > > {
724726 let tcx = infcx. tcx . global_tcx ( ) ;
725727 match ( ty. layout ( infcx) ?, & ty. sty ) {
726728 ( & Scalar { non_zero : true , .. } , _) |
727- ( & CEnum { non_zero : true , .. } , _) => Ok ( Some ( vec ! [ ] ) ) ,
729+ ( & CEnum { non_zero : true , .. } , _) => Ok ( Some ( ( vec ! [ ] , vec ! [ ] ) ) ) ,
728730 ( & FatPointer { non_zero : true , .. } , _) => {
729- Ok ( Some ( vec ! [ FAT_PTR_ADDR as u32 ] ) )
731+ Ok ( Some ( ( vec ! [ FAT_PTR_ADDR as u32 ] , vec ! [ FAT_PTR_ADDR as u32 ] ) ) )
730732 }
731733
732734 // Is this the NonZero lang item wrapping a pointer or integer type?
@@ -737,10 +739,11 @@ impl<'a, 'gcx, 'tcx> Struct {
737739 // FIXME(eddyb) also allow floating-point types here.
738740 Scalar { value : Int ( _) , non_zero : false } |
739741 Scalar { value : Pointer , non_zero : false } => {
740- Ok ( Some ( vec ! [ 0 ] ) )
742+ Ok ( Some ( ( vec ! [ 0 ] , vec ! [ 0 ] ) ) )
741743 }
742744 FatPointer { non_zero : false , .. } => {
743- Ok ( Some ( vec ! [ FAT_PTR_ADDR as u32 , 0 ] ) )
745+ let tmp = vec ! [ FAT_PTR_ADDR as u32 , 0 ] ;
746+ Ok ( Some ( ( tmp. clone ( ) , tmp) ) )
744747 }
745748 _ => Ok ( None )
746749 }
@@ -749,7 +752,7 @@ impl<'a, 'gcx, 'tcx> Struct {
749752 // Perhaps one of the fields of this struct is non-zero
750753 // let's recurse and find out
751754 ( & Univariant { ref variant, .. } , & ty:: TyAdt ( def, substs) ) if def. is_struct ( ) => {
752- Struct :: non_zero_field_path ( infcx, def. struct_variant ( ) . fields
755+ Struct :: non_zero_field_paths ( infcx, def. struct_variant ( ) . fields
753756 . iter ( ) . map ( |field| {
754757 field. ty ( tcx, substs)
755758 } ) ,
@@ -759,19 +762,19 @@ impl<'a, 'gcx, 'tcx> Struct {
759762 // Perhaps one of the upvars of this closure is non-zero
760763 ( & Univariant { ref variant, .. } , & ty:: TyClosure ( def, substs) ) => {
761764 let upvar_tys = substs. upvar_tys ( def, tcx) ;
762- Struct :: non_zero_field_path ( infcx, upvar_tys,
765+ Struct :: non_zero_field_paths ( infcx, upvar_tys,
763766 Some ( & variant. memory_index [ ..] ) )
764767 }
765768 // Can we use one of the fields in this tuple?
766769 ( & Univariant { ref variant, .. } , & ty:: TyTuple ( tys) ) => {
767- Struct :: non_zero_field_path ( infcx, tys. iter ( ) . cloned ( ) ,
770+ Struct :: non_zero_field_paths ( infcx, tys. iter ( ) . cloned ( ) ,
768771 Some ( & variant. memory_index [ ..] ) )
769772 }
770773
771774 // Is this a fixed-size array of something non-zero
772775 // with at least one element?
773776 ( _, & ty:: TyArray ( ety, d) ) if d > 0 => {
774- Struct :: non_zero_field_path ( infcx, Some ( ety) . into_iter ( ) , None )
777+ Struct :: non_zero_field_paths ( infcx, Some ( ety) . into_iter ( ) , None )
775778 }
776779
777780 ( _, & ty:: TyProjection ( _) ) | ( _, & ty:: TyAnon ( ..) ) => {
@@ -789,20 +792,23 @@ impl<'a, 'gcx, 'tcx> Struct {
789792
790793 /// Find the path leading to a non-zero leaf field, starting from
791794 /// the given set of fields and recursing through aggregates.
792- fn non_zero_field_path < I > ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
795+ // / Returns Some((path, source_path)) on success.
796+ /// `path` is translated to memory order. `source_path` is not.
797+ fn non_zero_field_paths < I > ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
793798 fields : I ,
794799 permutation : Option < & [ u32 ] > )
795- -> Result < Option < FieldPath > , LayoutError < ' gcx > >
800+ -> Result < Option < ( FieldPath , FieldPath ) > , LayoutError < ' gcx > >
796801 where I : Iterator < Item =Ty < ' gcx > > {
797802 for ( i, ty) in fields. enumerate ( ) {
798- if let Some ( mut path) = Struct :: non_zero_field_in_type ( infcx, ty) ? {
803+ if let Some ( ( mut path, mut source_path) ) = Struct :: non_zero_field_in_type ( infcx, ty) ? {
804+ source_path. push ( i as u32 ) ;
799805 let index = if let Some ( p) = permutation {
800806 p[ i] as usize
801807 } else {
802808 i
803809 } ;
804810 path. push ( index as u32 ) ;
805- return Ok ( Some ( path) ) ;
811+ return Ok ( Some ( ( path, source_path ) ) ) ;
806812 }
807813 }
808814 Ok ( None )
@@ -965,7 +971,9 @@ pub enum Layout {
965971 nndiscr : u64 ,
966972 nonnull : Struct ,
967973 // N.B. There is a 0 at the start, for LLVM GEP through a pointer.
968- discrfield : FieldPath
974+ discrfield : FieldPath ,
975+ // Like discrfield, but in source order. For debuginfo.
976+ discrfield_source : FieldPath
969977 }
970978}
971979
@@ -1242,10 +1250,11 @@ impl<'a, 'gcx, 'tcx> Layout {
12421250 if !Struct :: would_be_zero_sized ( dl, other_fields) ? {
12431251 continue ;
12441252 }
1245- let path = Struct :: non_zero_field_path ( infcx,
1253+ let paths = Struct :: non_zero_field_paths ( infcx,
12461254 variants[ discr] . iter ( ) . cloned ( ) ,
12471255 None ) ?;
1248- let mut path = if let Some ( p) = path { p } else { continue } ;
1256+ let ( mut path, mut path_source) = if let Some ( p) = paths { p }
1257+ else { continue } ;
12491258
12501259 // FIXME(eddyb) should take advantage of a newtype.
12511260 if path == & [ 0 ] && variants[ discr] . len ( ) == 1 {
@@ -1273,11 +1282,14 @@ impl<'a, 'gcx, 'tcx> Layout {
12731282 * path. last_mut ( ) . unwrap ( ) = i;
12741283 path. push ( 0 ) ; // For GEP through a pointer.
12751284 path. reverse ( ) ;
1285+ path_source. push ( 0 ) ;
1286+ path_source. reverse ( ) ;
12761287
12771288 return success ( StructWrappedNullablePointer {
12781289 nndiscr : discr as u64 ,
12791290 nonnull : st,
1280- discrfield : path
1291+ discrfield : path,
1292+ discrfield_source : path_source
12811293 } ) ;
12821294 }
12831295 }
0 commit comments