Skip to content

Commit 889a4eb

Browse files
committed
Deduplicate some code
1 parent df283df commit 889a4eb

File tree

1 file changed

+67
-73
lines changed

1 file changed

+67
-73
lines changed

src/librustc/ty/mod.rs

Lines changed: 67 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1823,64 +1823,77 @@ impl<'a, 'gcx, 'tcx> AdtDef {
18231823
}
18241824
}
18251825

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+
18261886
#[inline]
18271887
pub fn discriminants(&'a self, tcx: TyCtxt<'a, 'gcx, 'tcx>)
18281888
-> impl Iterator<Item=Discr<'tcx>> + 'a {
1829-
let param_env = ParamEnv::empty(traits::Reveal::UserFacing);
18301889
let repr_type = self.repr.discr_type();
18311890
let initial = repr_type.initial_discriminant(tcx.global_tcx());
18321891
let mut prev_discr = None::<Discr<'tcx>>;
18331892
self.variants.iter().map(move |v| {
18341893
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr(tcx));
18351894
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;
18841897
}
18851898
}
18861899
prev_discr = Some(discr);
@@ -1898,7 +1911,6 @@ impl<'a, 'gcx, 'tcx> AdtDef {
18981911
tcx: TyCtxt<'a, 'gcx, 'tcx>,
18991912
variant_index: usize)
19001913
-> Discr<'tcx> {
1901-
let param_env = ParamEnv::empty(traits::Reveal::UserFacing);
19021914
let repr_type = self.repr.discr_type();
19031915
let mut explicit_value = repr_type.initial_discriminant(tcx.global_tcx());
19041916
let mut explicit_index = variant_index;
@@ -1909,30 +1921,12 @@ impl<'a, 'gcx, 'tcx> AdtDef {
19091921
explicit_index -= distance;
19101922
}
19111923
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;
19281927
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 => {
19361930
if explicit_index == 0 {
19371931
break;
19381932
}

0 commit comments

Comments
 (0)