diff --git a/src/interpreter.rs b/src/interpreter.rs index 8db2f18f46fa..f1ec0c65e8a2 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -6,7 +6,7 @@ use std::error::Error; use std::fmt; use memory::{FieldRepr, Memory, Pointer, Repr}; -use primval; +use primval::{self, PrimVal}; const TRACE_EXECUTION: bool = true; @@ -277,7 +277,10 @@ impl<'a, 'tcx: 'a> Interpreter<'a, 'tcx> { ty::AdtKind::Enum => match dest_repr { Repr::Sum { ref discr, ref variants, .. } => { - // TODO(tsion): Write the discriminant value. + if discr.size() > 0 { + let discr_val = PrimVal::from_int(variant_idx as i64, discr); + try!(self.memory.write_primval(dest, discr_val)); + } self.assign_to_product( dest.offset(discr.size()), &variants[variant_idx], diff --git a/src/primval.rs b/src/primval.rs index 9442adbaf7e7..3fbcd6636404 100644 --- a/src/primval.rs +++ b/src/primval.rs @@ -1,5 +1,7 @@ use rustc::mir::repr as mir; +use memory::Repr; + #[derive(Clone, Copy, Debug, PartialEq)] pub enum PrimVal { Bool(bool), @@ -9,6 +11,19 @@ pub enum PrimVal { I64(i64), } +impl PrimVal { + pub fn from_int(n: i64, repr: &Repr) -> Self { + // TODO(tsion): Use checked casts. + match *repr { + Repr::I8 => PrimVal::I8(n as i8), + Repr::I16 => PrimVal::I16(n as i16), + Repr::I32 => PrimVal::I32(n as i32), + Repr::I64 => PrimVal::I64(n), + _ => panic!("attempted to make integer primval from non-integer repr"), + } + } +} + pub fn binary_op(bin_op: mir::BinOp, left: PrimVal, right: PrimVal) -> PrimVal { macro_rules! int_binops { ($v:ident, $l:ident, $r:ident) => ({ diff --git a/test/sums.rs b/test/sums.rs index e6545e81c00b..d04f0b2e7cf2 100644 --- a/test/sums.rs +++ b/test/sums.rs @@ -1,6 +1,25 @@ #![feature(custom_attribute)] #![allow(dead_code, unused_attributes)] +enum Unit { Unit } + +#[miri_run] +fn return_unit() -> Unit { + Unit::Unit +} + +enum MyBool { False, True } + +#[miri_run] +fn return_true() -> MyBool { + MyBool::True +} + +#[miri_run] +fn return_false() -> MyBool { + MyBool::False +} + #[miri_run] fn return_none() -> Option { None