about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2018-01-16 09:12:54 +0100
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2018-03-08 08:06:07 +0100
commit38b5ddd39b22dbdf9f004090146c561327ed51e7 (patch)
tree01d0868526c902cf2d8a40ac92b11035926dbfb9
parentcdcca786468a71375584bb48e3093790c91084f7 (diff)
downloadrust-38b5ddd39b22dbdf9f004090146c561327ed51e7.tar.gz
rust-38b5ddd39b22dbdf9f004090146c561327ed51e7.zip
Add a variant to ConstVal for storing miri results
-rw-r--r--src/librustc/ich/impls_ty.rs24
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/middle/const_val.rs3
-rw-r--r--src/librustc/mir/interpret/mod.rs11
-rw-r--r--src/librustc/mir/interpret/value.rs8
-rw-r--r--src/librustc/mir/mod.rs3
-rw-r--r--src/librustc/ty/context.rs19
-rw-r--r--src/librustc/ty/flags.rs1
-rw-r--r--src/librustc/ty/instance.rs4
-rw-r--r--src/librustc/ty/layout.rs2
-rw-r--r--src/librustc/ty/structural_impls.rs2
-rw-r--r--src/librustc/ty/walk.rs1
-rw-r--r--src/librustc/ty/wf.rs1
-rw-r--r--src/librustc_const_eval/pattern.rs1
-rw-r--r--src/librustc_metadata/decoder.rs46
-rw-r--r--src/librustc_metadata/encoder.rs39
-rw-r--r--src/librustc_mir/interpret/eval_context.rs23
-rw-r--r--src/librustc_trans/mir/constant.rs1
18 files changed, 165 insertions, 25 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index a8ed885e78d..06a60bfb0eb 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -21,6 +21,7 @@ use std::mem;
 use middle::region;
 use traits;
 use ty;
+use mir;
 
 impl<'gcx, T> HashStable<StableHashingContext<'gcx>>
 for &'gcx ty::Slice<T>
@@ -388,6 +389,9 @@ for ::middle::const_val::ConstVal<'gcx> {
                 def_id.hash_stable(hcx, hasher);
                 substs.hash_stable(hcx, hasher);
             }
+            Value(ref value) => {
+                value.hash_stable(hcx, hasher);
+            }
         }
     }
 }
@@ -396,6 +400,26 @@ impl_stable_hash_for!(struct ::middle::const_val::ByteArray<'tcx> {
     data
 });
 
+impl_stable_hash_for!(enum mir::interpret::Value {
+    ByVal(v),
+    ByValPair(a, b),
+    ByRef(ptr, align)
+});
+
+impl_stable_hash_for!(struct mir::interpret::MemoryPointer {
+    alloc_id,
+    offset
+});
+
+impl_stable_hash_for!(tuple_struct mir::interpret::AllocId{id});
+impl_stable_hash_for!(struct mir::interpret::Pointer{primval});
+
+impl_stable_hash_for!(enum mir::interpret::PrimVal {
+    Bytes(b),
+    Ptr(p),
+    Undef
+});
+
 impl_stable_hash_for!(struct ty::Const<'tcx> {
     ty,
     val
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index d08a41010ab..56de2939ffa 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -49,6 +49,7 @@
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
 #![feature(dyn_trait)]
+#![feature(entry_or_default)]
 #![feature(from_ref)]
 #![feature(fs_read_write)]
 #![feature(i128)]
diff --git a/src/librustc/middle/const_val.rs b/src/librustc/middle/const_val.rs
index 440af39a0d4..2309131c57a 100644
--- a/src/librustc/middle/const_val.rs
+++ b/src/librustc/middle/const_val.rs
@@ -14,6 +14,7 @@ use hir::def_id::DefId;
 use ty::{self, TyCtxt, layout};
 use ty::subst::Substs;
 use rustc_const_math::*;
+use mir::interpret::Value;
 
 use graphviz::IntoCow;
 use errors::DiagnosticBuilder;
@@ -38,6 +39,8 @@ pub enum ConstVal<'tcx> {
     Function(DefId, &'tcx Substs<'tcx>),
     Aggregate(ConstAggregate<'tcx>),
     Unevaluated(DefId, &'tcx Substs<'tcx>),
+    /// A miri value, currently only produced if old ctfe fails, but miri succeeds
+    Value(Value),
 }
 
 #[derive(Copy, Clone, Debug, Hash, RustcEncodable, Eq, PartialEq)]
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index a80695ec9b9..8b4f56e1dba 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -41,7 +41,7 @@ pub enum AccessKind {
 }
 
 /// Uniquely identifies a specific constant or static.
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
 pub struct GlobalId<'tcx> {
     /// For a constant or static, the `Instance` of the item itself.
     /// For a promoted global, the `Instance` of the function they belong to.
@@ -101,7 +101,7 @@ pub trait PointerArithmetic: layout::HasDataLayout {
 impl<T: layout::HasDataLayout> PointerArithmetic for T {}
 
 
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
 pub struct MemoryPointer {
     pub alloc_id: AllocId,
     pub offset: u64,
@@ -148,13 +148,16 @@ impl<'tcx> MemoryPointer {
 #[derive(Copy, Clone, Default, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
 pub struct AllocId(pub u64);
 
+impl ::rustc_serialize::UseSpecializedEncodable for AllocId {}
+impl ::rustc_serialize::UseSpecializedDecodable for AllocId {}
+
 impl fmt::Display for AllocId {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", self.0)
     }
 }
 
-#[derive(Debug, Eq, PartialEq, Hash)]
+#[derive(Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
 pub struct Allocation {
     /// The actual bytes of the allocation.
     /// Note that the bytes of a pointer represent the offset of the pointer
@@ -188,7 +191,7 @@ impl Allocation {
 type Block = u64;
 const BLOCK_SIZE: u64 = 64;
 
-#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+#[derive(Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
 pub struct UndefMask {
     blocks: Vec<Block>,
     len: u64,
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index 0bfff2a80e6..8d67856c0df 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -29,7 +29,7 @@ pub fn bytes_to_f64(bits: u128) -> ConstFloat {
 /// For optimization of a few very common cases, there is also a representation for a pair of
 /// primitive values (`ByValPair`). It allows Miri to avoid making allocations for checked binary
 /// operations and fat pointers. This idea was taken from rustc's trans.
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
 pub enum Value {
     ByRef(Pointer, Align),
     ByVal(PrimVal),
@@ -43,9 +43,9 @@ pub enum Value {
 /// I (@oli-obk) believe it is less easy to mix up generic primvals and primvals that are just
 /// the representation of pointers. Also all the sites that convert between primvals and pointers
 /// are explicit now (and rare!)
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
 pub struct Pointer {
-    primval: PrimVal,
+    pub primval: PrimVal,
 }
 
 impl<'tcx> Pointer {
@@ -138,7 +138,7 @@ impl ::std::convert::From<MemoryPointer> for Pointer {
 /// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
 /// size. Like a range of bytes in an `Allocation`, a `PrimVal` can either represent the raw bytes
 /// of a simple value, a pointer into another `Allocation`, or be undefined.
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
 pub enum PrimVal {
     /// The raw bytes of a simple value.
     Bytes(u128),
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 7c9feb506af..4c1b8cb79ed 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1881,7 +1881,8 @@ fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ConstVal) -> fmt::Result {
         Variant(def_id) |
         Function(def_id, _) => write!(fmt, "{}", item_path_str(def_id)),
         Aggregate(_) => bug!("`ConstVal::{:?}` should not be in MIR", const_val),
-        Unevaluated(..) => write!(fmt, "{:?}", const_val)
+        Unevaluated(..) => write!(fmt, "{:?}", const_val),
+        Value(val) => write!(fmt, "{:?}", val),
     }
 }
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 47a3580e867..520da34c40a 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -905,6 +905,11 @@ pub struct InterpretInterner<'tcx> {
     /// Allows obtaining const allocs via a unique identifier
     alloc_by_id: FxHashMap<interpret::AllocId, &'tcx interpret::Allocation>,
 
+    /// Reverse map of `alloc_cache`
+    ///
+    /// Multiple globals may share the same memory
+    global_cache: FxHashMap<interpret::Pointer, Vec<interpret::GlobalId<'tcx>>>,
+
     /// The AllocId to assign to the next new regular allocation.
     /// Always incremented, never gets smaller.
     next_id: interpret::AllocId,
@@ -955,11 +960,25 @@ impl<'tcx> InterpretInterner<'tcx> {
         global_id: interpret::GlobalId<'tcx>,
         ptr: interpret::AllocId,
     ) {
+        if let interpret::PrimVal::Ptr(ptr) = ptr.primval {
+            assert!(ptr.offset == 0);
+        }
+        self.global_cache.entry(ptr).or_default().push(global_id);
         if let Some(old) = self.alloc_cache.insert(global_id, ptr) {
             bug!("tried to cache {:?}, but was already existing as {:#?}", global_id, old);
         }
     }
 
+    pub fn get_globals(
+        &self,
+        ptr: interpret::Pointer,
+    ) -> &[interpret::GlobalId<'tcx>] {
+        match self.global_cache.get(&ptr) {
+            Some(v) => v,
+            None => &[],
+        }
+    }
+
     pub fn intern_at_reserved(
         &mut self,
         id: interpret::AllocId,
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index 2889322a1ce..60bf4afc2fc 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -224,6 +224,7 @@ impl FlagComputation {
             ConstVal::ByteStr(_) |
             ConstVal::Bool(_) |
             ConstVal::Char(_) |
+            ConstVal::Value(_) |
             ConstVal::Variant(_) => {}
             ConstVal::Function(_, substs) => {
                 self.add_substs(substs);
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index a5f0abb9bc0..614158bafa6 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -17,13 +17,13 @@ use util::ppaux;
 
 use std::fmt;
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct Instance<'tcx> {
     pub def: InstanceDef<'tcx>,
     pub substs: &'tcx Substs<'tcx>,
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub enum InstanceDef<'tcx> {
     Item(DefId),
     Intrinsic(DefId),
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 5069c595626..1aa7f671ad3 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -342,7 +342,7 @@ impl AddAssign for Size {
 /// Each field is a power of two, giving the alignment a maximum
 /// value of 2<sup>(2<sup>8</sup> - 1)</sup>, which is limited by LLVM to a i32, with
 /// a maximum capacity of 2<sup>31</sup> - 1 or 2147483647.
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
 pub struct Align {
     abi: u8,
     pref: u8,
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index 055835ed69c..3e7468d2cca 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -1249,6 +1249,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstVal<'tcx> {
             ConstVal::ByteStr(b) => ConstVal::ByteStr(b),
             ConstVal::Bool(b) => ConstVal::Bool(b),
             ConstVal::Char(c) => ConstVal::Char(c),
+            ConstVal::Value(v) => ConstVal::Value(v),
             ConstVal::Variant(def_id) => ConstVal::Variant(def_id),
             ConstVal::Function(def_id, substs) => {
                 ConstVal::Function(def_id, substs.fold_with(folder))
@@ -1304,6 +1305,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstVal<'tcx> {
             ConstVal::ByteStr(_) |
             ConstVal::Bool(_) |
             ConstVal::Char(_) |
+            ConstVal::Value(_) |
             ConstVal::Variant(_) => false,
             ConstVal::Function(_, substs) => substs.visit_with(visitor),
             ConstVal::Aggregate(ConstAggregate::Struct(fields)) => {
diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs
index 45f0ad1cf1a..4ef7706c45e 100644
--- a/src/librustc/ty/walk.rs
+++ b/src/librustc/ty/walk.rs
@@ -146,6 +146,7 @@ fn push_const<'tcx>(stack: &mut TypeWalkerStack<'tcx>, constant: &'tcx ty::Const
         ConstVal::ByteStr(_) |
         ConstVal::Bool(_) |
         ConstVal::Char(_) |
+        ConstVal::Value(_) |
         ConstVal::Variant(_) => {}
         ConstVal::Function(_, substs) => {
             stack.extend(substs.types().rev());
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index ea99bd39e87..443e0e857a7 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -224,6 +224,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
             ConstVal::Bool(_) |
             ConstVal::Char(_) |
             ConstVal::Variant(_) |
+            ConstVal::Value(_) |
             ConstVal::Function(..) => {}
             ConstVal::Aggregate(ConstAggregate::Struct(fields)) => {
                 for &(_, v) in fields {
diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs
index bdb1001124d..a09e2f2edd5 100644
--- a/src/librustc_const_eval/pattern.rs
+++ b/src/librustc_const_eval/pattern.rs
@@ -121,6 +121,7 @@ fn print_const_val(value: &ConstVal, f: &mut fmt::Formatter) -> fmt::Result {
         ConstVal::Variant(_) |
         ConstVal::Function(..) |
         ConstVal::Aggregate(_) |
+        ConstVal::Value(_) |
         ConstVal::Unevaluated(..) => bug!("{:?} not printable in a pattern", value)
     }
 }
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 60a0d4e03b5..3c3c489d0ff 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -24,11 +24,12 @@ use rustc::hir::def_id::{CrateNum, DefId, DefIndex,
                          CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc::ich::Fingerprint;
 use rustc::middle::lang_items;
-use rustc::mir;
+use rustc::mir::{self, interpret};
 use rustc::session::Session;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::codec::TyDecoder;
 use rustc::mir::Mir;
+use rustc::util::nodemap::FxHashMap;
 
 use std::cell::Ref;
 use std::collections::BTreeMap;
@@ -54,6 +55,9 @@ pub struct DecodeContext<'a, 'tcx: 'a> {
     last_filemap_index: usize,
 
     lazy_state: LazyState,
+
+    // interpreter allocation cache
+    interpret_alloc_cache: FxHashMap<usize, interpret::AllocId>,
 }
 
 /// Abstract over the various ways one can create metadata decoders.
@@ -72,6 +76,7 @@ pub trait Metadata<'a, 'tcx>: Copy {
             tcx,
             last_filemap_index: 0,
             lazy_state: LazyState::NoNode,
+            interpret_alloc_cache: FxHashMap::default(),
         }
     }
 }
@@ -268,6 +273,45 @@ impl<'a, 'tcx> SpecializedDecoder<DefIndex> for DecodeContext<'a, 'tcx> {
     }
 }
 
+impl<'a, 'tcx> SpecializedDecoder<interpret::AllocId> for DecodeContext<'a, 'tcx> {
+    fn specialized_decode(&mut self) -> Result<interpret::AllocId, Self::Error> {
+        const MAX1: usize = usize::max_value() - 1;
+        let mut interpret_interner = self.tcx.unwrap().interpret_interner.borrow_mut();
+        let pos = self.position();
+        match self.read_usize()? {
+            ::std::usize::MAX => {
+                let allocation = interpret::Allocation::decode(self)?;
+                let id = interpret_interner.reserve();
+                let allocation = self.tcx.unwrap().intern_const_alloc(allocation);
+                interpret_interner.intern_at_reserved(id, allocation);
+                let id = interpret::AllocId(id);
+                self.interpret_alloc_cache.insert(pos, id);
+
+                let num = usize::decode(self)?;
+                let ptr = interpret::Pointer {
+                    primval: interpret::PrimVal::Ptr(interpret::MemoryPointer {
+                        alloc_id: id,
+                        offset: 0,
+                    }),
+                };
+                for _ in 0..num {
+                    let glob = interpret::GlobalId::decode(self)?;
+                    interpret_interner.cache(glob, ptr);
+                }
+
+                Ok(id)
+            },
+            MAX1 => {
+                let instance = ty::Instance::decode(self)?;
+                let id = interpret::AllocId(interpret_interner.create_fn_alloc(instance));
+                self.interpret_alloc_cache.insert(pos, id);
+                Ok(id)
+            },
+            shorthand => Ok(self.interpret_alloc_cache[&shorthand]),
+        }
+    }
+}
+
 impl<'a, 'tcx> SpecializedDecoder<Span> for DecodeContext<'a, 'tcx> {
     fn specialized_decode(&mut self) -> Result<Span, Self::Error> {
         let tag = u8::decode(self)?;
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 830121b446f..928bf0a56ae 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -23,7 +23,7 @@ use rustc::middle::dependency_format::Linkage;
 use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel,
                                       metadata_symbol_name};
 use rustc::middle::lang_items;
-use rustc::mir;
+use rustc::mir::{self, interpret};
 use rustc::traits::specialization_graph;
 use rustc::ty::{self, Ty, TyCtxt, ReprOptions, SymbolName};
 use rustc::ty::codec::{self as ty_codec, TyEncoder};
@@ -59,6 +59,7 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
     lazy_state: LazyState,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
     predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
+    interpret_alloc_shorthands: FxHashMap<interpret::AllocId, usize>,
 
     // This is used to speed up Span encoding.
     filemap_cache: Lrc<FileMap>,
@@ -186,6 +187,41 @@ impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> {
     }
 }
 
+impl<'a, 'tcx> SpecializedEncoder<interpret::AllocId> for EncodeContext<'a, 'tcx> {
+    fn specialized_encode(&mut self, alloc_id: &interpret::AllocId) -> Result<(), Self::Error> {
+        if let Some(shorthand) = self.interpret_alloc_shorthands.get(alloc_id).cloned() {
+            return self.emit_usize(shorthand);
+        }
+        let start = self.position();
+        let interpret_interner = self.tcx.interpret_interner.borrow();
+        if let Some(alloc) = interpret_interner.get_alloc(alloc_id.0) {
+            usize::max_value().encode(self)?;
+            alloc.encode(self)?;
+            let globals = interpret_interner.get_globals(interpret::Pointer {
+                primval: interpret::PrimVal::Ptr(interpret::MemoryPointer {
+                    alloc_id: *alloc_id,
+                    offset: 0,
+                }),
+            });
+            globals.len().encode(self)?;
+            for glob in globals {
+                glob.encode(self)?;
+            }
+        } else if let Some(fn_instance) = interpret_interner.get_fn(alloc_id.0) {
+            (usize::max_value() - 1).encode(self)?;
+            fn_instance.encode(self)?;
+        } else {
+            bug!("alloc id without corresponding allocation: {}", alloc_id.0);
+        }
+        let len = self.position() - start * 7;
+        // Check that the shorthand is a not longer than the
+        // full encoding itself, i.e. it's an obvious win.
+        assert!(len >= 64 || (start as u64) < (1 << len));
+        self.interpret_alloc_shorthands.insert(*alloc_id, start);
+        Ok(())
+    }
+}
+
 impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext<'a, 'tcx> {
     fn specialized_encode(&mut self,
                           predicates: &ty::GenericPredicates<'tcx>)
@@ -1699,6 +1735,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             type_shorthands: Default::default(),
             predicate_shorthands: Default::default(),
             filemap_cache: tcx.sess.codemap().files()[0].clone(),
+            interpret_alloc_shorthands: Default::default(),
         };
 
         // Encode the rustc version string in a predictable location.
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 25f933c5da6..e9e8ccd03b1 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -241,24 +241,24 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
     }
 
     pub(super) fn const_to_value(&mut self, const_val: &ConstVal<'tcx>, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
-        use rustc::middle::const_val::ConstVal::*;
+        use rustc::middle::const_val::ConstVal;
 
         let primval = match *const_val {
-            Integral(const_int) => PrimVal::Bytes(const_int.to_u128_unchecked()),
+            ConstVal::Integral(const_int) => PrimVal::Bytes(const_int.to_u128_unchecked()),
 
-            Float(val) => PrimVal::Bytes(val.bits),
+            ConstVal::Float(val) => PrimVal::Bytes(val.bits),
 
-            Bool(b) => PrimVal::from_bool(b),
-            Char(c) => PrimVal::from_char(c),
+            ConstVal::Bool(b) => PrimVal::from_bool(b),
+            ConstVal::Char(c) => PrimVal::from_char(c),
 
-            Str(ref s) => return self.str_to_value(s),
+            ConstVal::Str(ref s) => return self.str_to_value(s),
 
-            ByteStr(ref bs) => {
+            ConstVal::ByteStr(ref bs) => {
                 let ptr = self.memory.allocate_cached(bs.data);
                 PrimVal::Ptr(ptr)
             }
 
-            Unevaluated(def_id, substs) => {
+            ConstVal::Unevaluated(def_id, substs) => {
                 let instance = self.resolve(def_id, substs)?;
                 return Ok(self.read_global_as_value(GlobalId {
                     instance,
@@ -266,10 +266,11 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
                 }, self.layout_of(ty)?));
             }
 
-            Aggregate(..) |
-            Variant(_) => bug!("should not have aggregate or variant constants in MIR"),
+            ConstVal::Aggregate(..) |
+            ConstVal::Variant(_) => bug!("should not have aggregate or variant constants in MIR"),
             // function items are zero sized and thus have no readable value
-            Function(..) => PrimVal::Undef,
+            ConstVal::Function(..) => PrimVal::Undef,
+            ConstVal::Value(val) => return Ok(val),
         };
 
         Ok(Value::ByVal(primval))
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index d470f92b752..c853230b15a 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -108,6 +108,7 @@ impl<'a, 'tcx> Const<'tcx> {
             ConstVal::Unevaluated(..) => {
                 bug!("MIR must not use `{:?}` (aggregates are expanded to MIR rvalues)", cv)
             }
+            ConstVal::Value(_) => unimplemented!(),
         };
 
         assert!(!ty.has_erasable_regions());