@@ -558,8 +558,7 @@ impl<'a, 'gcx, 'tcx> Struct {
558
558
( & Univariant { non_zero : true , .. } , & ty:: TyStruct ( def, substs) ) => {
559
559
let fields = & def. struct_variant ( ) . fields ;
560
560
assert_eq ! ( fields. len( ) , 1 ) ;
561
- let ty = normalize_associated_type ( infcx, fields[ 0 ] . ty ( tcx, substs) ) ;
562
- match * ty. layout ( infcx) ? {
561
+ match * fields[ 0 ] . ty ( tcx, substs) . layout ( infcx) ? {
563
562
// FIXME(eddyb) also allow floating-point types here.
564
563
Scalar { value : Int ( _) , non_zero : false } |
565
564
Scalar { value : Pointer , non_zero : false } => {
@@ -577,7 +576,7 @@ impl<'a, 'gcx, 'tcx> Struct {
577
576
( _, & ty:: TyStruct ( def, substs) ) => {
578
577
Struct :: non_zero_field_path ( infcx, def. struct_variant ( ) . fields
579
578
. iter ( ) . map ( |field| {
580
- normalize_associated_type ( infcx , field. ty ( tcx, substs) )
579
+ field. ty ( tcx, substs)
581
580
} ) )
582
581
}
583
582
@@ -595,6 +594,14 @@ impl<'a, 'gcx, 'tcx> Struct {
595
594
Struct :: non_zero_field_path ( infcx, Some ( ety) . into_iter ( ) )
596
595
}
597
596
597
+ ( _, & ty:: TyProjection ( _) ) => {
598
+ let normalized = normalize_associated_type ( infcx, ty) ;
599
+ if ty == normalized {
600
+ return Ok ( None ) ;
601
+ }
602
+ return Struct :: non_zero_field_in_type ( infcx, normalized) ;
603
+ }
604
+
598
605
// Anything else is not a non-zero type.
599
606
_ => Ok ( None )
600
607
}
@@ -762,8 +769,9 @@ fn normalize_associated_type<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
762
769
impl < ' a , ' gcx , ' tcx > Layout {
763
770
pub fn compute_uncached ( ty : Ty < ' gcx > ,
764
771
infcx : & InferCtxt < ' a , ' gcx , ' tcx > )
765
- -> Result < Layout , LayoutError < ' gcx > > {
772
+ -> Result < & ' gcx Layout , LayoutError < ' gcx > > {
766
773
let tcx = infcx. tcx . global_tcx ( ) ;
774
+ let success = |layout| Ok ( tcx. intern_layout ( layout) ) ;
767
775
let dl = & tcx. data_layout ;
768
776
assert ! ( !ty. has_infer_types( ) ) ;
769
777
@@ -795,6 +803,7 @@ impl<'a, 'gcx, 'tcx> Layout {
795
803
if pointee. is_sized ( tcx, & infcx. parameter_environment , DUMMY_SP ) {
796
804
Scalar { value : Pointer , non_zero : non_zero }
797
805
} else {
806
+ let pointee = normalize_associated_type ( infcx, pointee) ;
798
807
let unsized_part = tcx. struct_tail ( pointee) ;
799
808
let meta = match unsized_part. sty {
800
809
ty:: TySlice ( _) | ty:: TyStr => {
@@ -860,7 +869,7 @@ impl<'a, 'gcx, 'tcx> Layout {
860
869
let element = ty. simd_type ( tcx) ;
861
870
match * element. layout ( infcx) ? {
862
871
Scalar { value, .. } => {
863
- return Ok ( Vector {
872
+ return success ( Vector {
864
873
element : value,
865
874
count : ty. simd_size ( tcx) as u64
866
875
} ) ;
@@ -873,8 +882,7 @@ impl<'a, 'gcx, 'tcx> Layout {
873
882
}
874
883
}
875
884
let fields = def. struct_variant ( ) . fields . iter ( ) . map ( |field| {
876
- normalize_associated_type ( infcx, field. ty ( tcx, substs) )
877
- . layout ( infcx)
885
+ field. ty ( tcx, substs) . layout ( infcx)
878
886
} ) ;
879
887
let packed = tcx. lookup_packed ( def. did ) ;
880
888
let mut st = Struct :: new ( dl, packed) ;
@@ -914,7 +922,7 @@ impl<'a, 'gcx, 'tcx> Layout {
914
922
915
923
let mut st = Struct :: new ( dl, false ) ;
916
924
st. extend ( dl, drop_flag. iter ( ) . map ( Ok ) , ty) ?;
917
- return Ok ( Univariant { variant : st, non_zero : false } ) ;
925
+ return success ( Univariant { variant : st, non_zero : false } ) ;
918
926
}
919
927
920
928
if !dtor && def. variants . iter ( ) . all ( |v| v. fields . is_empty ( ) ) {
@@ -927,7 +935,7 @@ impl<'a, 'gcx, 'tcx> Layout {
927
935
}
928
936
929
937
let ( discr, signed) = Integer :: repr_discr ( tcx, hint, min, max) ;
930
- return Ok ( CEnum {
938
+ return success ( CEnum {
931
939
discr : discr,
932
940
signed : signed,
933
941
min : min as u64 ,
@@ -950,19 +958,16 @@ impl<'a, 'gcx, 'tcx> Layout {
950
958
// (Typechecking will reject discriminant-sizing attrs.)
951
959
assert_eq ! ( hint, attr:: ReprAny ) ;
952
960
let fields = def. variants [ 0 ] . fields . iter ( ) . map ( |field| {
953
- normalize_associated_type ( infcx, field. ty ( tcx, substs) )
954
- . layout ( infcx)
961
+ field. ty ( tcx, substs) . layout ( infcx)
955
962
} ) ;
956
963
let mut st = Struct :: new ( dl, false ) ;
957
964
st. extend ( dl, fields. chain ( drop_flag. iter ( ) . map ( Ok ) ) , ty) ?;
958
- return Ok ( Univariant { variant : st, non_zero : false } ) ;
965
+ return success ( Univariant { variant : st, non_zero : false } ) ;
959
966
}
960
967
961
968
// Cache the substituted and normalized variant field types.
962
969
let variants = def. variants . iter ( ) . map ( |v| {
963
- v. fields . iter ( ) . map ( |field| {
964
- normalize_associated_type ( infcx, field. ty ( tcx, substs) )
965
- } ) . collect :: < Vec < _ > > ( )
970
+ v. fields . iter ( ) . map ( |field| field. ty ( tcx, substs) ) . collect :: < Vec < _ > > ( )
966
971
} ) . collect :: < Vec < _ > > ( ) ;
967
972
968
973
if !dtor && variants. len ( ) == 2 && hint == attr:: ReprAny {
@@ -982,7 +987,7 @@ impl<'a, 'gcx, 'tcx> Layout {
982
987
if path == & [ 0 ] && variants[ discr] . len ( ) == 1 {
983
988
match * variants[ discr] [ 0 ] . layout ( infcx) ? {
984
989
Scalar { value, .. } => {
985
- return Ok ( RawNullablePointer {
990
+ return success ( RawNullablePointer {
986
991
nndiscr : discr as u64 ,
987
992
value : value
988
993
} ) ;
@@ -998,10 +1003,8 @@ impl<'a, 'gcx, 'tcx> Layout {
998
1003
path. push ( 0 ) ; // For GEP through a pointer.
999
1004
path. reverse ( ) ;
1000
1005
let mut st = Struct :: new ( dl, false ) ;
1001
- st. extend ( dl, variants[ discr] . iter ( ) . map ( |ty| {
1002
- ty. layout ( infcx)
1003
- } ) , ty) ?;
1004
- return Ok ( StructWrappedNullablePointer {
1006
+ st. extend ( dl, variants[ discr] . iter ( ) . map ( |ty| ty. layout ( infcx) ) , ty) ?;
1007
+ return success ( StructWrappedNullablePointer {
1005
1008
nndiscr : discr as u64 ,
1006
1009
nonnull : st,
1007
1010
discrfield : path
@@ -1105,15 +1108,22 @@ impl<'a, 'gcx, 'tcx> Layout {
1105
1108
}
1106
1109
1107
1110
// Types with no meaningful known layout.
1108
- ty:: TyProjection ( _) | ty:: TyParam ( _) => {
1111
+ ty:: TyProjection ( _) => {
1112
+ let normalized = normalize_associated_type ( infcx, ty) ;
1113
+ if ty == normalized {
1114
+ return Err ( LayoutError :: Unknown ( ty) ) ;
1115
+ }
1116
+ return normalized. layout ( infcx) ;
1117
+ }
1118
+ ty:: TyParam ( _) => {
1109
1119
return Err ( LayoutError :: Unknown ( ty) ) ;
1110
1120
}
1111
1121
ty:: TyInfer ( _) | ty:: TyError => {
1112
1122
bug ! ( "Layout::compute: unexpected type `{}`" , ty)
1113
1123
}
1114
1124
} ;
1115
1125
1116
- Ok ( layout)
1126
+ success ( layout)
1117
1127
}
1118
1128
1119
1129
/// Returns true if the layout corresponds to an unsized type.
@@ -1272,8 +1282,7 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
1272
1282
// Get a zero-sized variant or a pointer newtype.
1273
1283
let zero_or_ptr_variant = |i : usize | {
1274
1284
let fields = def. variants [ i] . fields . iter ( ) . map ( |field| {
1275
- let ty = normalize_associated_type ( infcx, & field. ty ( tcx, substs) ) ;
1276
- SizeSkeleton :: compute ( ty, infcx)
1285
+ SizeSkeleton :: compute ( field. ty ( tcx, substs) , infcx)
1277
1286
} ) ;
1278
1287
let mut ptr = None ;
1279
1288
for field in fields {
@@ -1323,6 +1332,15 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
1323
1332
}
1324
1333
}
1325
1334
1335
+ ty:: TyProjection ( _) => {
1336
+ let normalized = normalize_associated_type ( infcx, ty) ;
1337
+ if ty == normalized {
1338
+ Err ( err)
1339
+ } else {
1340
+ SizeSkeleton :: compute ( normalized, infcx)
1341
+ }
1342
+ }
1343
+
1326
1344
_ => Err ( err)
1327
1345
}
1328
1346
}
0 commit comments