tcx.intern_tup(&[ty, tcx.types.bool])
}
Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx),
- Rvalue::Discriminant(ref place) => {
- place.ty(local_decls, tcx).ty.discriminant_type(tcx)
- }
+ Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx),
Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t),
Rvalue::NullaryOp(NullOp::SizeOf, _) => tcx.types.usize,
Rvalue::Aggregate(ref ak, ref ops) => match **ak {
self.flags.contains(ReprFlags::HIDE_NICHE)
}
+ /// Returns the discriminant type, given these `repr` options.
+ /// This must only be called on enums!
pub fn discr_type(&self) -> attr::IntType {
self.int.unwrap_or(attr::SignedInt(ast::IntTy::Isize))
}
#[inline]
pub fn eval_explicit_discr(&self, tcx: TyCtxt<'tcx>, expr_did: DefId) -> Option<Discr<'tcx>> {
+ assert!(self.is_enum());
let param_env = tcx.param_env(expr_did);
let repr_type = self.repr.discr_type();
match tcx.const_eval_poly(expr_did) {
&'tcx self,
tcx: TyCtxt<'tcx>,
) -> impl Iterator<Item = (VariantIdx, Discr<'tcx>)> + Captures<'tcx> {
+ assert!(self.is_enum());
let repr_type = self.repr.discr_type();
let initial = repr_type.initial_discriminant(tcx);
let mut prev_discr = None::<Discr<'tcx>>;
tcx: TyCtxt<'tcx>,
variant_index: VariantIdx,
) -> Discr<'tcx> {
+ assert!(self.is_enum());
let (val, offset) = self.discriminant_def_for_variant(variant_index);
let explicit_value = val
.and_then(|expr_did| self.eval_explicit_discr(tcx, expr_did))
variant_index: VariantIdx,
) -> Option<Discr<'tcx>> {
match self.kind {
- TyKind::Adt(adt, _) => Some(adt.discriminant_for_variant(tcx, variant_index)),
+ TyKind::Adt(adt, _) if adt.is_enum() => {
+ Some(adt.discriminant_for_variant(tcx, variant_index))
+ }
TyKind::Generator(def_id, substs, _) => {
Some(substs.as_generator().discriminant_for_variant(def_id, tcx, variant_index))
}
}
/// Returns the type of the discriminant of this type.
- pub fn discriminant_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
+ pub fn discriminant_ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
match self.kind {
- ty::Adt(adt_def, _) => adt_def.repr.discr_type().to_ty(tcx),
+ ty::Adt(adt, _) if adt.is_enum() => adt.repr.discr_type().to_ty(tcx),
ty::Generator(_, substs, _) => substs.as_generator().discr_ty(tcx),
- _ => bug!("{:?} does not have a discriminant", self),
+ _ => {
+ // This can only be `0`, for now, so `u8` will suffice.
+ tcx.types.u8
+ }
}
}
trace!("read_discriminant_value {:#?}", op.layout);
// Get type and layout of the discriminant.
- let discr_layout = self.layout_of(op.layout.ty.discriminant_type(*self.tcx))?;
+ let discr_layout = self.layout_of(op.layout.ty.discriminant_ty(*self.tcx))?;
trace!("discriminant type: {:?}", discr_layout.ty);
- // We use "discriminant" to refer to the value associated with a particualr enum variant.
+ // We use "discriminant" to refer to the value associated with a particular enum variant.
// This is not to be confused with its "variant index", which is just determining its position in the
// declared list of variants -- they can differ with explicitly assigned discriminants.
// We use "tag" to refer to how the discriminant is encoded in memory, which can be either