@@ -597,7 +597,8 @@ impl<'a, 'gcx, 'tcx> Struct {
597
597
-> Result < Option < FieldPath > , LayoutError < ' gcx > > {
598
598
let tcx = infcx. tcx . global_tcx ( ) ;
599
599
match ( ty. layout ( infcx) ?, & ty. sty ) {
600
- ( & Scalar { non_zero : true , .. } , _) => Ok ( Some ( vec ! [ ] ) ) ,
600
+ ( & Scalar { non_zero : true , .. } , _) |
601
+ ( & CEnum { non_zero : true , .. } , _) => Ok ( Some ( vec ! [ ] ) ) ,
601
602
( & FatPointer { non_zero : true , .. } , _) => {
602
603
Ok ( Some ( vec ! [ FAT_PTR_ADDR as u32 ] ) )
603
604
}
@@ -769,6 +770,7 @@ pub enum Layout {
769
770
CEnum {
770
771
discr : Integer ,
771
772
signed : bool ,
773
+ non_zero : bool ,
772
774
// Inclusive discriminant range.
773
775
// If min > max, it represents min...u64::MAX followed by 0...max.
774
776
// FIXME(eddyb) always use the shortest range, e.g. by finding
@@ -1002,9 +1004,10 @@ impl<'a, 'gcx, 'tcx> Layout {
1002
1004
1003
1005
if def. is_enum ( ) && def. variants . iter ( ) . all ( |v| v. fields . is_empty ( ) ) {
1004
1006
// All bodies empty -> intlike
1005
- let ( mut min, mut max) = ( i64:: MAX , i64:: MIN ) ;
1007
+ let ( mut min, mut max, mut non_zero ) = ( i64:: MAX , i64:: MIN , true ) ;
1006
1008
for v in & def. variants {
1007
1009
let x = v. disr_val . to_u64_unchecked ( ) as i64 ;
1010
+ if x == 0 { non_zero = false ; }
1008
1011
if x < min { min = x; }
1009
1012
if x > max { max = x; }
1010
1013
}
@@ -1013,6 +1016,7 @@ impl<'a, 'gcx, 'tcx> Layout {
1013
1016
return success ( CEnum {
1014
1017
discr : discr,
1015
1018
signed : signed,
1019
+ non_zero : non_zero,
1016
1020
min : min as u64 ,
1017
1021
max : max as u64
1018
1022
} ) ;
@@ -1069,19 +1073,17 @@ impl<'a, 'gcx, 'tcx> Layout {
1069
1073
1070
1074
// FIXME(eddyb) should take advantage of a newtype.
1071
1075
if path == & [ 0 ] && variants[ discr] . len ( ) == 1 {
1072
- match * variants[ discr] [ 0 ] . layout ( infcx) ? {
1073
- Scalar { value, .. } => {
1074
- return success ( RawNullablePointer {
1075
- nndiscr : discr as u64 ,
1076
- value : value
1077
- } ) ;
1078
- }
1079
- _ => {
1080
- bug ! ( "Layout::compute: `{}`'s non-zero \
1081
- `{}` field not scalar?!",
1082
- ty, variants[ discr] [ 0 ] )
1083
- }
1084
- }
1076
+ let value = match * variants[ discr] [ 0 ] . layout ( infcx) ? {
1077
+ Scalar { value, .. } => value,
1078
+ CEnum { discr, .. } => Int ( discr) ,
1079
+ _ => bug ! ( "Layout::compute: `{}`'s non-zero \
1080
+ `{}` field not scalar?!",
1081
+ ty, variants[ discr] [ 0 ] )
1082
+ } ;
1083
+ return success ( RawNullablePointer {
1084
+ nndiscr : discr as u64 ,
1085
+ value : value,
1086
+ } ) ;
1085
1087
}
1086
1088
1087
1089
path. push ( 0 ) ; // For GEP through a pointer.
0 commit comments