@@ -717,16 +717,18 @@ impl<'a, 'gcx, 'tcx> Struct {
717
717
718
718
/// Find the path leading to a non-zero leaf field, starting from
719
719
/// 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.
720
722
// FIXME(eddyb) track value ranges and traverse already optimized enums.
721
723
fn non_zero_field_in_type ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > ,
722
724
ty : Ty < ' gcx > )
723
- -> Result < Option < FieldPath > , LayoutError < ' gcx > > {
725
+ -> Result < Option < ( FieldPath , FieldPath ) > , LayoutError < ' gcx > > {
724
726
let tcx = infcx. tcx . global_tcx ( ) ;
725
727
match ( ty. layout ( infcx) ?, & ty. sty ) {
726
728
( & Scalar { non_zero : true , .. } , _) |
727
- ( & CEnum { non_zero : true , .. } , _) => Ok ( Some ( vec ! [ ] ) ) ,
729
+ ( & CEnum { non_zero : true , .. } , _) => Ok ( Some ( ( vec ! [ ] , vec ! [ ] ) ) ) ,
728
730
( & 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 ] ) ) )
730
732
}
731
733
732
734
// Is this the NonZero lang item wrapping a pointer or integer type?
@@ -737,10 +739,11 @@ impl<'a, 'gcx, 'tcx> Struct {
737
739
// FIXME(eddyb) also allow floating-point types here.
738
740
Scalar { value : Int ( _) , non_zero : false } |
739
741
Scalar { value : Pointer , non_zero : false } => {
740
- Ok ( Some ( vec ! [ 0 ] ) )
742
+ Ok ( Some ( ( vec ! [ 0 ] , vec ! [ 0 ] ) ) )
741
743
}
742
744
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) ) )
744
747
}
745
748
_ => Ok ( None )
746
749
}
@@ -749,7 +752,7 @@ impl<'a, 'gcx, 'tcx> Struct {
749
752
// Perhaps one of the fields of this struct is non-zero
750
753
// let's recurse and find out
751
754
( & 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
753
756
. iter ( ) . map ( |field| {
754
757
field. ty ( tcx, substs)
755
758
} ) ,
@@ -759,19 +762,19 @@ impl<'a, 'gcx, 'tcx> Struct {
759
762
// Perhaps one of the upvars of this closure is non-zero
760
763
( & Univariant { ref variant, .. } , & ty:: TyClosure ( def, substs) ) => {
761
764
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,
763
766
Some ( & variant. memory_index [ ..] ) )
764
767
}
765
768
// Can we use one of the fields in this tuple?
766
769
( & 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 ( ) ,
768
771
Some ( & variant. memory_index [ ..] ) )
769
772
}
770
773
771
774
// Is this a fixed-size array of something non-zero
772
775
// with at least one element?
773
776
( _, & 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 )
775
778
}
776
779
777
780
( _, & ty:: TyProjection ( _) ) | ( _, & ty:: TyAnon ( ..) ) => {
@@ -789,20 +792,23 @@ impl<'a, 'gcx, 'tcx> Struct {
789
792
790
793
/// Find the path leading to a non-zero leaf field, starting from
791
794
/// 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 > ,
793
798
fields : I ,
794
799
permutation : Option < & [ u32 ] > )
795
- -> Result < Option < FieldPath > , LayoutError < ' gcx > >
800
+ -> Result < Option < ( FieldPath , FieldPath ) > , LayoutError < ' gcx > >
796
801
where I : Iterator < Item =Ty < ' gcx > > {
797
802
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 ) ;
799
805
let index = if let Some ( p) = permutation {
800
806
p[ i] as usize
801
807
} else {
802
808
i
803
809
} ;
804
810
path. push ( index as u32 ) ;
805
- return Ok ( Some ( path) ) ;
811
+ return Ok ( Some ( ( path, source_path ) ) ) ;
806
812
}
807
813
}
808
814
Ok ( None )
@@ -965,7 +971,9 @@ pub enum Layout {
965
971
nndiscr : u64 ,
966
972
nonnull : Struct ,
967
973
// 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
969
977
}
970
978
}
971
979
@@ -1242,10 +1250,11 @@ impl<'a, 'gcx, 'tcx> Layout {
1242
1250
if !Struct :: would_be_zero_sized ( dl, other_fields) ? {
1243
1251
continue ;
1244
1252
}
1245
- let path = Struct :: non_zero_field_path ( infcx,
1253
+ let paths = Struct :: non_zero_field_paths ( infcx,
1246
1254
variants[ discr] . iter ( ) . cloned ( ) ,
1247
1255
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 } ;
1249
1258
1250
1259
// FIXME(eddyb) should take advantage of a newtype.
1251
1260
if path == & [ 0 ] && variants[ discr] . len ( ) == 1 {
@@ -1273,11 +1282,14 @@ impl<'a, 'gcx, 'tcx> Layout {
1273
1282
* path. last_mut ( ) . unwrap ( ) = i;
1274
1283
path. push ( 0 ) ; // For GEP through a pointer.
1275
1284
path. reverse ( ) ;
1285
+ path_source. push ( 0 ) ;
1286
+ path_source. reverse ( ) ;
1276
1287
1277
1288
return success ( StructWrappedNullablePointer {
1278
1289
nndiscr : discr as u64 ,
1279
1290
nonnull : st,
1280
- discrfield : path
1291
+ discrfield : path,
1292
+ discrfield_source : path_source
1281
1293
} ) ;
1282
1294
}
1283
1295
}
0 commit comments