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 { + 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::(tcx, enc, qri)?; encode_query_results::(tcx, enc, qri)?; encode_query_results::(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 for CacheDecoder<'a, ' tcx.interpret_interner.intern_at_reserved(alloc_id, allocation); if let Some(glob) = Option::::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))