summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_query_impl/src/on_disk_cache.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_query_impl/src/on_disk_cache.rs')
-rw-r--r--compiler/rustc_query_impl/src/on_disk_cache.rs76
1 files changed, 75 insertions, 1 deletions
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 56fd90c98..0e93f3ce1 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -22,8 +22,9 @@ use rustc_span::hygiene::{
ExpnId, HygieneDecodeContext, HygieneEncodeContext, SyntaxContext, SyntaxContextData,
};
use rustc_span::source_map::{SourceMap, StableSourceFileId};
-use rustc_span::CachingSourceMapView;
use rustc_span::{BytePos, ExpnData, ExpnHash, Pos, SourceFile, Span};
+use rustc_span::{CachingSourceMapView, Symbol};
+use std::collections::hash_map::Entry;
use std::io;
use std::mem;
@@ -38,6 +39,11 @@ const TAG_RELATIVE_SPAN: u8 = 2;
const TAG_SYNTAX_CONTEXT: u8 = 0;
const TAG_EXPN_DATA: u8 = 1;
+// Tags for encoding Symbol's
+const SYMBOL_STR: u8 = 0;
+const SYMBOL_OFFSET: u8 = 1;
+const SYMBOL_PREINTERNED: u8 = 2;
+
/// Provides an interface to incremental compilation data cached from the
/// previous compilation session. This data will eventually include the results
/// of a few selected queries (like `typeck` and `mir_optimized`) and
@@ -254,6 +260,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> {
source_map: CachingSourceMapView::new(tcx.sess.source_map()),
file_to_file_index,
hygiene_context: &hygiene_encode_context,
+ symbol_table: Default::default(),
};
// Encode query results.
@@ -714,6 +721,40 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Span {
}
}
+// copy&paste impl from rustc_metadata
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Symbol {
+ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+ let tag = d.read_u8();
+
+ match tag {
+ SYMBOL_STR => {
+ let s = d.read_str();
+ Symbol::intern(s)
+ }
+ SYMBOL_OFFSET => {
+ // read str offset
+ let pos = d.read_usize();
+ let old_pos = d.opaque.position();
+
+ // move to str ofset and read
+ d.opaque.set_position(pos);
+ let s = d.read_str();
+ let sym = Symbol::intern(s);
+
+ // restore position
+ d.opaque.set_position(old_pos);
+
+ sym
+ }
+ SYMBOL_PREINTERNED => {
+ let symbol_index = d.read_u32();
+ Symbol::new_from_decoded(symbol_index)
+ }
+ _ => unreachable!(),
+ }
+ }
+}
+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum {
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
let stable_id = StableCrateId::decode(d);
@@ -757,6 +798,12 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashSet<LocalDefId>
}
}
+impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx FxHashMap<DefId, Ty<'tcx>> {
+ fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+ RefDecodable::decode(d)
+ }
+}
+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
for &'tcx IndexVec<mir::Promoted, mir::Body<'tcx>>
{
@@ -815,6 +862,7 @@ pub struct CacheEncoder<'a, 'tcx> {
source_map: CachingSourceMapView<'tcx>,
file_to_file_index: FxHashMap<*const SourceFile, SourceFileIndex>,
hygiene_context: &'a HygieneEncodeContext,
+ symbol_table: FxHashMap<Symbol, usize>,
}
impl<'a, 'tcx> CacheEncoder<'a, 'tcx> {
@@ -899,6 +947,32 @@ impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Span {
}
}
+// copy&paste impl from rustc_metadata
+impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Symbol {
+ fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
+ // if symbol preinterned, emit tag and symbol index
+ if self.is_preinterned() {
+ s.encoder.emit_u8(SYMBOL_PREINTERNED);
+ s.encoder.emit_u32(self.as_u32());
+ } else {
+ // otherwise write it as string or as offset to it
+ match s.symbol_table.entry(*self) {
+ Entry::Vacant(o) => {
+ s.encoder.emit_u8(SYMBOL_STR);
+ let pos = s.encoder.position();
+ o.insert(pos);
+ s.emit_str(self.as_str());
+ }
+ Entry::Occupied(o) => {
+ let x = o.get().clone();
+ s.emit_u8(SYMBOL_OFFSET);
+ s.emit_usize(x);
+ }
+ }
+ }
+ }
+}
+
impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
type I = TyCtxt<'tcx>;
const CLEAR_CROSS_CRATE: bool = false;