diff --git a/src/librustc/ty/maps/config.rs b/src/librustc/ty/maps/config.rs
index 21affcbc9ede7..bcd58e993044d 100644
--- a/src/librustc/ty/maps/config.rs
+++ b/src/librustc/ty/maps/config.rs
@@ -156,6 +156,18 @@ impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
     fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> String {
         format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id()))
     }
+
+    #[inline]
+    fn cache_on_disk(_key: Self::Key) -> bool {
+        true
+    }
+
+    #[inline]
+    fn try_load_from_disk<'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                              id: SerializedDepNodeIndex)
+                              -> Option<Self::Value> {
+        tcx.on_disk_query_result_cache.try_load_query_result(tcx, id).map(Ok)
+    }
 }
 
 impl<'tcx> QueryDescription<'tcx> for queries::mir_keys<'tcx> {
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 0ded759fec730..27eb7de2d06aa 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -82,7 +82,7 @@ pub use self::on_disk_cache::OnDiskCache;
 // the driver creates (using several `rustc_*` crates).
 //
 // The result of query must implement Clone. They must also implement ty::maps::values::Value
-// which produces an appropiate error value if the query resulted in a query cycle.
+// which produces an appropriate error value if the query resulted in a query cycle.
 // Queries marked with `fatal_cycle` do not need that implementation
 // as they will raise an fatal error on query cycles instead.
 define_maps! { <'tcx>
diff --git a/src/librustc/ty/maps/on_disk_cache.rs b/src/librustc/ty/maps/on_disk_cache.rs
index 49c4b8bc49d8c..35e874b74d9ae 100644
--- a/src/librustc/ty/maps/on_disk_cache.rs
+++ b/src/librustc/ty/maps/on_disk_cache.rs
@@ -221,6 +221,24 @@ impl<'sess> OnDiskCache<'sess> {
                 encode_query_results::<symbol_name, _>(tcx, enc, qri)?;
                 encode_query_results::<check_match, _>(tcx, enc, qri)?;
                 encode_query_results::<trans_fn_attrs, _>(tcx, enc, qri)?;
+
+                // const eval is special, it only encodes successfully evaluated constants
+                use ty::maps::plumbing::GetCacheInternal;
+                for (key, entry) in const_eval::get_cache_internal(tcx).map.iter() {
+                    use ty::maps::config::QueryDescription;
+                    if const_eval::cache_on_disk(key.clone()) {
+                        if let Ok(ref value) = entry.value {
+                            let dep_node = SerializedDepNodeIndex::new(entry.index.index());
+
+                            // Record position of the cache entry
+                            qri.push((dep_node, AbsoluteBytePos::new(enc.position())));
+
+                            // Encode the type check tables with the SerializedDepNodeIndex
+                            // as tag.
+                            enc.encode_tagged(dep_node, value)?;
+                        }
+                    }
+                }
             }
 
             // Encode diagnostics
@@ -563,6 +581,7 @@ impl<'a, 'tcx, 'x> SpecializedDecoder<interpret::AllocId> for CacheDecoder<'a, '
                 tcx.interpret_interner.intern_at_reserved(alloc_id, allocation);
 
                 if let Some(glob) = Option::<DefId>::decode(self)? {
+                    trace!("connecting alloc {:?} with {:?}", alloc_id, glob);
                     tcx.interpret_interner.cache(glob, alloc_id);
                 }
 
diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs
index ee5874be9d70a..82eb28287b033 100644
--- a/src/librustc_mir/interpret/const_eval.rs
+++ b/src/librustc_mir/interpret/const_eval.rs
@@ -110,6 +110,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
         span = mir.span;
         let layout = ecx.layout_of(mir.return_ty().subst(tcx, cid.instance.substs))?;
         let alloc = tcx.interpret_interner.get_cached(cid.instance.def_id());
+        let is_static = tcx.is_static(cid.instance.def_id()).is_some();
         let alloc = match alloc {
             Some(alloc) => {
                 assert!(cid.promoted.is_none());
@@ -123,7 +124,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
                     layout.align,
                     None,
                 )?;
-                if tcx.is_static(cid.instance.def_id()).is_some() {
+                if is_static {
                     tcx.interpret_interner.cache(cid.instance.def_id(), ptr.alloc_id);
                 }
                 let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span);
@@ -151,8 +152,11 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
             }
         };
         let ptr = MemoryPointer::new(alloc, 0).into();
+        // always try to read the value and report errors
         let value = match ecx.try_read_value(ptr, layout.align, layout.ty)? {
-            Some(val) => val,
+            // if it's a constant (so it needs no address, directly compute its value)
+            Some(val) if !is_static => val,
+            // point at the allocation
             _ => Value::ByRef(ptr, layout.align),
         };
         Ok((value, ptr, layout.ty))