Change:
I was trying to build which pulls in pango 0.1.3 as dependency . While building pango, rustc segfaults  meta: Crash happens in So apparently const eval produces a discriminant that doesn't match any variant's discriminant. more concretely, it happens during a match on which is the only discriminant with as its value.
weird, I am still getting the panic with todays nightly :(
Same backtrace? We do have a regression test for this exact issue
Yeah, backtrace is identical except for the rustc version string in the ICE notes. :/
Fix confirmed, thanks!

Discussion:
} let (mut min, mut max) = (i128::max_value(), i128::min_value()); <ins> let discr_type = def.repr.discr_type(); let bits = Integer::from_attr(tcx, discr_type).size().bits(); </ins> for (i, discr) in def.discriminants(tcx).enumerate() { if variants[i].iter().any(|f| f.abi == Abi::Uninhabited) { continue; } <del> let x = discr.val as i128; </del> <ins> let mut x = discr.val as i128; if discr_type.is_signed() { // sign extend the raw representation to be an i128 x = (x << (128 - bits)) >> (128 - bits); } </ins> if x < min { min = x; } if x > max { max = x; } }

) -> Option<Discr<'tcx>> { let param_env = ParamEnv::empty(); let repr_type = self.repr.discr_type(); <del> let bit_size = layout::Integer::from_attr(tcx, repr_type).size().bits(); </del> let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did); let instance = ty::Instance::new(expr_did, substs); let cid = GlobalId {

match tcx.const_eval(param_env.and(cid)) { Ok(&ty::Const { val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))), <del> .. </del> <ins> ty, </ins> }) => { trace!("discriminants: {} ({:?})", b, repr_type); <del> let ty = repr_type.to_ty(tcx); if repr_type.is_signed() { let val = b as i128; // sign extend to i128 let amt = 128 - bit_size; let val = (val << amt) >> amt; Some(Discr { val: val as u128, ty, }) } else { Some(Discr { val: b, ty, }) } </del> <ins> Some(Discr { val: b, ty, }) </ins> }, Ok(&ty::Const { val: ConstVal::Value(other),

#[derive(Copy, Clone, Debug)] pub struct Discr<'tcx> { <ins> /// bit representation of the discriminant, so `-128i8` is `0xFF_u128` </ins> pub val: u128, pub ty: Ty<'tcx> } impl<'tcx> fmt::Display for Discr<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { <del> if self.ty.is_signed() { write!(fmt, "{}", self.val as i128) } else { write!(fmt, "{}", self.val) </del> <ins> match self.ty.sty { ty::TyInt(ity) => { let bits = ty::tls::with(|tcx| { Integer::from_attr(tcx, SignedInt(ity)).size().bits() }); let x = self.val as i128; // sign extend the raw representation to be an i128 let x = (x << (128 - bits)) >> (128 - bits); write!(fmt, "{}", x) }, _ => write!(fmt, "{}", self.val), </ins> } } }

TyUint(uty) => (Integer::from_attr(tcx, UnsignedInt(uty)), false), _ => bug!("non integer discriminant"), }; <ins> let bit_size = int.size().bits(); let amt = 128 - bit_size; </ins> if signed { <del> let (min, max) = match int { Integer::I8 => (i8::min_value() as i128, i8::max_value() as i128), Integer::I16 => (i16::min_value() as i128, i16::max_value() as i128), Integer::I32 => (i32::min_value() as i128, i32::max_value() as i128), Integer::I64 => (i64::min_value() as i128, i64::max_value() as i128), Integer::I128 => (i128::min_value(), i128::max_value()), </del> <ins> let sext = |u| { let i = u as i128; (i << amt) >> amt </ins> }; <del> let val = self.val as i128; </del> <ins> let min = sext(1_u128 << (bit_size - 1)); let max = i128::max_value() >> amt; let val = sext(self.val); assert!(n < (i128::max_value() as u128)); </ins> let n = n as i128; let oflo = val > max - n; let val = if oflo {

} else { val + n }; <ins> // zero the upper bits let val = val as u128; let val = (val << amt) >> amt; </ins> (Self { val: val as u128, ty: self.ty, }, oflo) } else { <del> let (min, max) = match int { Integer::I8 => (u8::min_value() as u128, u8::max_value() as u128), Integer::I16 => (u16::min_value() as u128, u16::max_value() as u128), Integer::I32 => (u32::min_value() as u128, u32::max_value() as u128), Integer::I64 => (u64::min_value() as u128, u64::max_value() as u128), Integer::I128 => (u128::min_value(), u128::max_value()), }; </del> <ins> let max = u128::max_value() >> amt; </ins> let val = self.val; let oflo = val > max - n; let val = if oflo { <del> min + (n - (max - val) - 1) </del> <ins> n - (max - val) - 1 </ins> } else { val + n };

<ins> // Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. // https://github.com/rust-lang/rust/issues/49181 #[derive(Eq, PartialEq)] #[repr(i8)] pub enum A { B = -1, C = 1, } pub const D: A = A::B; fn main() { match A::C { D => {}, _ => {} } } </ins>