@@ -1823,64 +1823,77 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1823
1823
}
1824
1824
}
1825
1825
1826
+ #[ inline]
1827
+ fn eval_explicit_discr (
1828
+ & self ,
1829
+ tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
1830
+ expr_did : DefId ,
1831
+ ) -> Option < Discr < ' tcx > > {
1832
+ let param_env = ParamEnv :: empty ( traits:: Reveal :: UserFacing ) ;
1833
+ let repr_type = self . repr . discr_type ( ) ;
1834
+ let substs = Substs :: identity_for_item ( tcx. global_tcx ( ) , expr_did) ;
1835
+ let instance = ty:: Instance :: new ( expr_did, substs) ;
1836
+ let cid = GlobalId {
1837
+ instance,
1838
+ promoted : None
1839
+ } ;
1840
+ match tcx. const_eval ( param_env. and ( cid) ) {
1841
+ Ok ( & ty:: Const {
1842
+ val : ConstVal :: Value ( Value :: ByVal ( PrimVal :: Bytes ( b) ) ) ,
1843
+ ..
1844
+ } ) => {
1845
+ trace ! ( "discriminants: {} ({:?})" , b, repr_type) ;
1846
+ let ty = repr_type. to_ty ( tcx) ;
1847
+ if ty. is_signed ( ) {
1848
+ let ( ty, param_env) = tcx
1849
+ . lift_to_global ( & ( ty, param_env) )
1850
+ . unwrap_or_else ( || {
1851
+ bug ! ( "MIR: discriminants({:?}, {:?}) got \
1852
+ type with inference types/regions",
1853
+ ty, param_env) ;
1854
+ } ) ;
1855
+ let size = tcx. global_tcx ( )
1856
+ . layout_of ( param_env. and ( ty) )
1857
+ . expect ( "int layout" )
1858
+ . size
1859
+ . bits ( ) ;
1860
+ let val = b as i128 ;
1861
+ // sign extend to i128
1862
+ let amt = 128 - size;
1863
+ let val = ( val << amt) >> amt;
1864
+ Some ( Discr {
1865
+ val : val as u128 ,
1866
+ ty,
1867
+ } )
1868
+ } else {
1869
+ Some ( Discr {
1870
+ val : b,
1871
+ ty,
1872
+ } )
1873
+ }
1874
+ }
1875
+ _ => {
1876
+ if !expr_did. is_local ( ) {
1877
+ span_bug ! ( tcx. def_span( expr_did) ,
1878
+ "variant discriminant evaluation succeeded \
1879
+ in its crate but failed locally") ;
1880
+ }
1881
+ None
1882
+ }
1883
+ }
1884
+ }
1885
+
1826
1886
#[ inline]
1827
1887
pub fn discriminants ( & ' a self , tcx : TyCtxt < ' a , ' gcx , ' tcx > )
1828
1888
-> impl Iterator < Item =Discr < ' tcx > > + ' a {
1829
- let param_env = ParamEnv :: empty ( traits:: Reveal :: UserFacing ) ;
1830
1889
let repr_type = self . repr . discr_type ( ) ;
1831
1890
let initial = repr_type. initial_discriminant ( tcx. global_tcx ( ) ) ;
1832
1891
let mut prev_discr = None :: < Discr < ' tcx > > ;
1833
1892
self . variants . iter ( ) . map ( move |v| {
1834
1893
let mut discr = prev_discr. map_or ( initial, |d| d. wrap_incr ( tcx) ) ;
1835
1894
if let VariantDiscr :: Explicit ( expr_did) = v. discr {
1836
- let substs = Substs :: identity_for_item ( tcx. global_tcx ( ) , expr_did) ;
1837
- let instance = ty:: Instance :: new ( expr_did, substs) ;
1838
- let cid = GlobalId {
1839
- instance,
1840
- promoted : None
1841
- } ;
1842
- match tcx. const_eval ( param_env. and ( cid) ) {
1843
- Ok ( & ty:: Const {
1844
- val : ConstVal :: Value ( Value :: ByVal ( PrimVal :: Bytes ( b) ) ) ,
1845
- ..
1846
- } ) => {
1847
- trace ! ( "discriminants: {} ({:?})" , b, repr_type) ;
1848
- let ty = repr_type. to_ty ( tcx) ;
1849
- if ty. is_signed ( ) {
1850
- let ( ty, param_env) = tcx
1851
- . lift_to_global ( & ( ty, param_env) )
1852
- . unwrap_or_else ( || {
1853
- bug ! ( "MIR: discriminants({:?}, {:?}) got \
1854
- type with inference types/regions",
1855
- ty, param_env) ;
1856
- } ) ;
1857
- let size = tcx. global_tcx ( )
1858
- . layout_of ( param_env. and ( ty) )
1859
- . expect ( "int layout" )
1860
- . size
1861
- . bits ( ) ;
1862
- let val = b as i128 ;
1863
- // sign extend to i128
1864
- let amt = 128 - size;
1865
- let val = ( val << amt) >> amt;
1866
- discr = Discr {
1867
- val : val as u128 ,
1868
- ty,
1869
- } ;
1870
- } else {
1871
- discr = Discr {
1872
- val : b,
1873
- ty,
1874
- } ;
1875
- }
1876
- }
1877
- _ => {
1878
- if !expr_did. is_local ( ) {
1879
- span_bug ! ( tcx. def_span( expr_did) ,
1880
- "variant discriminant evaluation succeeded \
1881
- in its crate but failed locally") ;
1882
- }
1883
- }
1895
+ if let Some ( new_discr) = self . eval_explicit_discr ( tcx, expr_did) {
1896
+ discr = new_discr;
1884
1897
}
1885
1898
}
1886
1899
prev_discr = Some ( discr) ;
@@ -1898,7 +1911,6 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1898
1911
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
1899
1912
variant_index : usize )
1900
1913
-> Discr < ' tcx > {
1901
- let param_env = ParamEnv :: empty ( traits:: Reveal :: UserFacing ) ;
1902
1914
let repr_type = self . repr . discr_type ( ) ;
1903
1915
let mut explicit_value = repr_type. initial_discriminant ( tcx. global_tcx ( ) ) ;
1904
1916
let mut explicit_index = variant_index;
@@ -1909,30 +1921,12 @@ impl<'a, 'gcx, 'tcx> AdtDef {
1909
1921
explicit_index -= distance;
1910
1922
}
1911
1923
ty:: VariantDiscr :: Explicit ( expr_did) => {
1912
- let substs = Substs :: identity_for_item ( tcx. global_tcx ( ) , expr_did) ;
1913
- let instance = ty:: Instance :: new ( expr_did, substs) ;
1914
- let cid = GlobalId {
1915
- instance,
1916
- promoted : None
1917
- } ;
1918
- match tcx. const_eval ( param_env. and ( cid) ) {
1919
- Ok ( & ty:: Const {
1920
- val : ConstVal :: Value ( Value :: ByVal ( PrimVal :: Bytes ( b) ) ) ,
1921
- ..
1922
- } ) => {
1923
- trace ! ( "discriminants: {} ({:?})" , b, repr_type) ;
1924
- explicit_value = Discr {
1925
- val : b,
1926
- ty : repr_type. to_ty ( tcx) ,
1927
- } ;
1924
+ match self . eval_explicit_discr ( tcx, expr_did) {
1925
+ Some ( discr) => {
1926
+ explicit_value = discr;
1928
1927
break ;
1929
- }
1930
- _ => {
1931
- if !expr_did. is_local ( ) {
1932
- span_bug ! ( tcx. def_span( expr_did) ,
1933
- "variant discriminant evaluation succeeded \
1934
- in its crate but failed locally") ;
1935
- }
1928
+ } ,
1929
+ None => {
1936
1930
if explicit_index == 0 {
1937
1931
break ;
1938
1932
}
0 commit comments