Remove almost all uses of specialization from the metadata encoding code

This commit is contained in:
bjorn3 2023-12-31 20:27:35 +00:00
parent 6ed37bdc42
commit 8d598b0d58
7 changed files with 307 additions and 290 deletions

View File

@ -409,21 +409,6 @@ impl<'a, 'tcx> TyDecoder for DecodeContext<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for CrateNum {
#[inline]
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> CrateNum {
let cnum = CrateNum::from_u32(d.read_u32());
d.map_encoded_cnum_to_current(cnum)
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefIndex {
#[inline]
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefIndex {
DefIndex::from_u32(d.read_u32())
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnIndex { impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnIndex {
#[inline] #[inline]
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ExpnIndex { fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ExpnIndex {
@ -439,11 +424,24 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ast::AttrId {
} }
} }
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext { impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SyntaxContext { fn decode_crate_num(&mut self) -> CrateNum {
let cdata = decoder.cdata(); let cnum = CrateNum::from_u32(self.read_u32());
self.map_encoded_cnum_to_current(cnum)
}
let Some(sess) = decoder.sess else { fn decode_def_index(&mut self) -> DefIndex {
DefIndex::from_u32(self.read_u32())
}
fn decode_def_id(&mut self) -> DefId {
DefId { krate: Decodable::decode(self), index: Decodable::decode(self) }
}
fn decode_syntax_context(&mut self) -> SyntaxContext {
let cdata = self.cdata();
let Some(sess) = self.sess else {
bug!( bug!(
"Cannot decode SyntaxContext without Session.\ "Cannot decode SyntaxContext without Session.\
You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`."
@ -451,7 +449,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
}; };
let cname = cdata.root.name(); let cname = cdata.root.name();
rustc_span::hygiene::decode_syntax_context(decoder, &cdata.hygiene_context, |_, id| { rustc_span::hygiene::decode_syntax_context(self, &cdata.hygiene_context, |_, id| {
debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id); debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
cdata cdata
.root .root
@ -461,21 +459,19 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
.decode((cdata, sess)) .decode((cdata, sess))
}) })
} }
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId { fn decode_expn_id(&mut self) -> ExpnId {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> ExpnId { let local_cdata = self.cdata();
let local_cdata = decoder.cdata();
let Some(sess) = decoder.sess else { let Some(sess) = self.sess else {
bug!( bug!(
"Cannot decode ExpnId without Session. \ "Cannot decode ExpnId without Session. \
You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`."
); );
}; };
let cnum = CrateNum::decode(decoder); let cnum = CrateNum::decode(self);
let index = u32::decode(decoder); let index = u32::decode(self);
let expn_id = rustc_span::hygiene::decode_expn_id(cnum, index, |expn_id| { let expn_id = rustc_span::hygiene::decode_expn_id(cnum, index, |expn_id| {
let ExpnId { krate: cnum, local_id: index } = expn_id; let ExpnId { krate: cnum, local_id: index } = expn_id;
@ -503,9 +499,7 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
}); });
expn_id expn_id
} }
}
impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
fn decode_span(&mut self) -> Span { fn decode_span(&mut self) -> Span {
let start = self.position(); let start = self.position();
let tag = SpanTag(self.peek_byte()); let tag = SpanTag(self.peek_byte());
@ -524,6 +518,32 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
}; };
Span::new(data.lo, data.hi, data.ctxt, data.parent) Span::new(data.lo, data.hi, data.ctxt, data.parent)
} }
fn decode_symbol(&mut self) -> Symbol {
let tag = self.read_u8();
match tag {
SYMBOL_STR => {
let s = self.read_str();
Symbol::intern(s)
}
SYMBOL_OFFSET => {
// read str offset
let pos = self.read_usize();
// move to str offset and read
self.opaque.with_position(pos, |d| {
let s = d.read_str();
Symbol::intern(s)
})
}
SYMBOL_PREINTERNED => {
let symbol_index = self.read_u32();
Symbol::new_from_decoded(symbol_index)
}
_ => unreachable!(),
}
}
} }
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SpanData { impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SpanData {
@ -631,34 +651,6 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SpanData {
} }
} }
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Symbol {
fn decode(d: &mut DecodeContext<'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();
// move to str offset and read
d.opaque.with_position(pos, |d| {
let s = d.read_str();
Symbol::intern(s)
})
}
SYMBOL_PREINTERNED => {
let symbol_index = d.read_u32();
Symbol::new_from_decoded(symbol_index)
}
_ => unreachable!(),
}
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] { impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self { fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d) ty::codec::RefDecodable::decode(d)

View File

@ -125,48 +125,45 @@ impl<'a, 'tcx, I, T> Encodable<EncodeContext<'a, 'tcx>> for LazyTable<I, T> {
} }
} }
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for CrateNum {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
if *self != LOCAL_CRATE && s.is_proc_macro {
panic!("Attempted to encode non-local CrateNum {self:?} for proc-macro crate");
}
s.emit_u32(self.as_u32());
}
}
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for DefIndex {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
s.emit_u32(self.as_u32());
}
}
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnIndex { impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnIndex {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) { fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
s.emit_u32(self.as_u32()); s.emit_u32(self.as_u32());
} }
} }
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SyntaxContext { impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) { fn encode_crate_num(&mut self, crate_num: CrateNum) {
rustc_span::hygiene::raw_encode_syntax_context(*self, s.hygiene_ctxt, s); if crate_num != LOCAL_CRATE && self.is_proc_macro {
panic!("Attempted to encode non-local CrateNum {crate_num:?} for proc-macro crate");
}
self.emit_u32(crate_num.as_u32());
} }
}
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId { fn encode_def_index(&mut self, def_index: DefIndex) {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) { self.emit_u32(def_index.as_u32());
if self.krate == LOCAL_CRATE { }
fn encode_def_id(&mut self, def_id: DefId) {
def_id.krate.encode(self);
def_id.index.encode(self);
}
fn encode_syntax_context(&mut self, syntax_context: SyntaxContext) {
rustc_span::hygiene::raw_encode_syntax_context(syntax_context, self.hygiene_ctxt, self);
}
fn encode_expn_id(&mut self, expn_id: ExpnId) {
if expn_id.krate == LOCAL_CRATE {
// We will only write details for local expansions. Non-local expansions will fetch // We will only write details for local expansions. Non-local expansions will fetch
// data from the corresponding crate's metadata. // data from the corresponding crate's metadata.
// FIXME(#43047) FIXME(#74731) We may eventually want to avoid relying on external // FIXME(#43047) FIXME(#74731) We may eventually want to avoid relying on external
// metadata from proc-macro crates. // metadata from proc-macro crates.
s.hygiene_ctxt.schedule_expn_data_for_encoding(*self); self.hygiene_ctxt.schedule_expn_data_for_encoding(expn_id);
} }
self.krate.encode(s); expn_id.krate.encode(self);
self.local_id.encode(s); expn_id.local_id.encode(self);
} }
}
impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> {
fn encode_span(&mut self, span: Span) { fn encode_span(&mut self, span: Span) {
match self.span_shorthands.entry(span) { match self.span_shorthands.entry(span) {
Entry::Occupied(o) => { Entry::Occupied(o) => {
@ -192,6 +189,29 @@ impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> {
} }
} }
} }
fn encode_symbol(&mut self, symbol: Symbol) {
// if symbol preinterned, emit tag and symbol index
if symbol.is_preinterned() {
self.opaque.emit_u8(SYMBOL_PREINTERNED);
self.opaque.emit_u32(symbol.as_u32());
} else {
// otherwise write it as string or as offset to it
match self.symbol_table.entry(symbol) {
Entry::Vacant(o) => {
self.opaque.emit_u8(SYMBOL_STR);
let pos = self.opaque.position();
o.insert(pos);
self.emit_str(symbol.as_str());
}
Entry::Occupied(o) => {
let x = *o.get();
self.emit_u8(SYMBOL_OFFSET);
self.emit_usize(x);
}
}
}
}
} }
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData { impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
@ -337,31 +357,6 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SpanData {
} }
} }
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Symbol {
fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) {
// if symbol preinterned, emit tag and symbol index
if self.is_preinterned() {
s.opaque.emit_u8(SYMBOL_PREINTERNED);
s.opaque.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.opaque.emit_u8(SYMBOL_STR);
let pos = s.opaque.position();
o.insert(pos);
s.emit_str(self.as_str());
}
Entry::Occupied(o) => {
let x = *o.get();
s.emit_u8(SYMBOL_OFFSET);
s.emit_usize(x);
}
}
}
}
}
impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for [u8] { impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for [u8] {
fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) { fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) {
Encoder::emit_usize(e, self.len()); Encoder::emit_usize(e, self.len());

View File

@ -583,10 +583,10 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Vec<u8> {
} }
} }
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext { impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self { fn decode_syntax_context(&mut self) -> SyntaxContext {
let syntax_contexts = decoder.syntax_contexts; let syntax_contexts = self.syntax_contexts;
rustc_span::hygiene::decode_syntax_context(decoder, decoder.hygiene_context, |this, id| { rustc_span::hygiene::decode_syntax_context(self, self.hygiene_context, |this, id| {
// This closure is invoked if we haven't already decoded the data for the `SyntaxContext` we are deserializing. // This closure is invoked if we haven't already decoded the data for the `SyntaxContext` we are deserializing.
// We look up the position of the associated `SyntaxData` and decode it. // We look up the position of the associated `SyntaxData` and decode it.
let pos = syntax_contexts.get(&id).unwrap(); let pos = syntax_contexts.get(&id).unwrap();
@ -596,11 +596,9 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for SyntaxContext {
}) })
}) })
} }
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId { fn decode_expn_id(&mut self) -> ExpnId {
fn decode(decoder: &mut CacheDecoder<'a, 'tcx>) -> Self { let hash = ExpnHash::decode(self);
let hash = ExpnHash::decode(decoder);
if hash.is_root() { if hash.is_root() {
return ExpnId::root(); return ExpnId::root();
} }
@ -609,23 +607,23 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
return expn_id; return expn_id;
} }
let krate = decoder.tcx.stable_crate_id_to_crate_num(hash.stable_crate_id()); let krate = self.tcx.stable_crate_id_to_crate_num(hash.stable_crate_id());
let expn_id = if krate == LOCAL_CRATE { let expn_id = if krate == LOCAL_CRATE {
// We look up the position of the associated `ExpnData` and decode it. // We look up the position of the associated `ExpnData` and decode it.
let pos = decoder let pos = self
.expn_data .expn_data
.get(&hash) .get(&hash)
.unwrap_or_else(|| panic!("Bad hash {:?} (map {:?})", hash, decoder.expn_data)); .unwrap_or_else(|| panic!("Bad hash {:?} (map {:?})", hash, self.expn_data));
let data: ExpnData = decoder let data: ExpnData =
.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA)); self.with_position(pos.to_usize(), |decoder| decode_tagged(decoder, TAG_EXPN_DATA));
let expn_id = rustc_span::hygiene::register_local_expn_id(data, hash); let expn_id = rustc_span::hygiene::register_local_expn_id(data, hash);
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
let local_hash = decoder.tcx.with_stable_hashing_context(|mut hcx| { let local_hash = self.tcx.with_stable_hashing_context(|mut hcx| {
let mut hasher = StableHasher::new(); let mut hasher = StableHasher::new();
expn_id.expn_data().hash_stable(&mut hcx, &mut hasher); expn_id.expn_data().hash_stable(&mut hcx, &mut hasher);
hasher.finish() hasher.finish()
@ -635,9 +633,9 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
expn_id expn_id
} else { } else {
let index_guess = decoder.foreign_expn_data[&hash]; let index_guess = self.foreign_expn_data[&hash];
decoder.tcx.cstore_untracked().expn_hash_to_expn_id( self.tcx.cstore_untracked().expn_hash_to_expn_id(
decoder.tcx.sess, self.tcx.sess,
krate, krate,
index_guess, index_guess,
hash, hash,
@ -647,9 +645,7 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for ExpnId {
debug_assert_eq!(expn_id.krate, krate); debug_assert_eq!(expn_id.krate, krate);
expn_id expn_id
} }
}
impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
fn decode_span(&mut self) -> Span { fn decode_span(&mut self) -> Span {
let ctxt = SyntaxContext::decode(self); let ctxt = SyntaxContext::decode(self);
let parent = Option::<LocalDefId>::decode(self); let parent = Option::<LocalDefId>::decode(self);
@ -686,72 +682,62 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
Span::new(lo, hi, ctxt, parent) Span::new(lo, hi, ctxt, parent)
} }
}
// copy&paste impl from rustc_metadata // copy&paste impl from rustc_metadata
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for Symbol {
#[inline] #[inline]
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { fn decode_symbol(&mut self) -> Symbol {
let tag = d.read_u8(); let tag = self.read_u8();
match tag { match tag {
SYMBOL_STR => { SYMBOL_STR => {
let s = d.read_str(); let s = self.read_str();
Symbol::intern(s) Symbol::intern(s)
} }
SYMBOL_OFFSET => { SYMBOL_OFFSET => {
// read str offset // read str offset
let pos = d.read_usize(); let pos = self.read_usize();
// move to str offset and read // move to str offset and read
d.opaque.with_position(pos, |d| { self.opaque.with_position(pos, |d| {
let s = d.read_str(); let s = d.read_str();
Symbol::intern(s) Symbol::intern(s)
}) })
} }
SYMBOL_PREINTERNED => { SYMBOL_PREINTERNED => {
let symbol_index = d.read_u32(); let symbol_index = self.read_u32();
Symbol::new_from_decoded(symbol_index) Symbol::new_from_decoded(symbol_index)
} }
_ => unreachable!(), _ => unreachable!(),
} }
} }
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for CrateNum { fn decode_crate_num(&mut self) -> CrateNum {
#[inline] let stable_id = StableCrateId::decode(self);
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { let cnum = self.tcx.stable_crate_id_to_crate_num(stable_id);
let stable_id = StableCrateId::decode(d);
let cnum = d.tcx.stable_crate_id_to_crate_num(stable_id);
cnum cnum
} }
}
// This impl makes sure that we get a runtime error when we try decode a // This impl makes sure that we get a runtime error when we try decode a
// `DefIndex` that is not contained in a `DefId`. Such a case would be problematic // `DefIndex` that is not contained in a `DefId`. Such a case would be problematic
// because we would not know how to transform the `DefIndex` to the current // because we would not know how to transform the `DefIndex` to the current
// context. // context.
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefIndex { fn decode_def_index(&mut self) -> DefIndex {
fn decode(_d: &mut CacheDecoder<'a, 'tcx>) -> DefIndex {
panic!("trying to decode `DefIndex` outside the context of a `DefId`") panic!("trying to decode `DefIndex` outside the context of a `DefId`")
} }
}
// Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two // Both the `CrateNum` and the `DefIndex` of a `DefId` can change in between two
// compilation sessions. We use the `DefPathHash`, which is stable across // compilation sessions. We use the `DefPathHash`, which is stable across
// sessions, to map the old `DefId` to the new one. // sessions, to map the old `DefId` to the new one.
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for DefId { fn decode_def_id(&mut self) -> DefId {
#[inline]
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
// Load the `DefPathHash` which is was we encoded the `DefId` as. // Load the `DefPathHash` which is was we encoded the `DefId` as.
let def_path_hash = DefPathHash::decode(d); let def_path_hash = DefPathHash::decode(self);
// Using the `DefPathHash`, we can lookup the new `DefId`. // Using the `DefPathHash`, we can lookup the new `DefId`.
// Subtle: We only encode a `DefId` as part of a query result. // Subtle: We only encode a `DefId` as part of a query result.
// If we get to this point, then all of the query inputs were green, // If we get to this point, then all of the query inputs were green,
// which means that the definition with this hash is guaranteed to // which means that the definition with this hash is guaranteed to
// still exist in the current compilation session. // still exist in the current compilation session.
d.tcx.def_path_hash_to_def_id(def_path_hash, &mut || { self.tcx.def_path_hash_to_def_id(def_path_hash, &mut || {
panic!("Failed to convert DefPathHash {def_path_hash:?}") panic!("Failed to convert DefPathHash {def_path_hash:?}")
}) })
} }
@ -860,20 +846,16 @@ impl<'a, 'tcx> CacheEncoder<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for SyntaxContext {
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
rustc_span::hygiene::raw_encode_syntax_context(*self, s.hygiene_context, s);
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for ExpnId {
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
s.hygiene_context.schedule_expn_data_for_encoding(*self);
self.expn_hash().encode(s);
}
}
impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> { impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> {
fn encode_syntax_context(&mut self, syntax_context: SyntaxContext) {
rustc_span::hygiene::raw_encode_syntax_context(syntax_context, self.hygiene_context, self);
}
fn encode_expn_id(&mut self, expn_id: ExpnId) {
self.hygiene_context.schedule_expn_data_for_encoding(expn_id);
expn_id.expn_hash().encode(self);
}
fn encode_span(&mut self, span: Span) { fn encode_span(&mut self, span: Span) {
let span_data = span.data_untracked(); let span_data = span.data_untracked();
span_data.ctxt.encode(self); span_data.ctxt.encode(self);
@ -915,32 +897,42 @@ impl<'a, 'tcx> SpanEncoder for CacheEncoder<'a, 'tcx> {
col_lo.encode(self); col_lo.encode(self);
len.encode(self); len.encode(self);
} }
}
// copy&paste impl from rustc_metadata // copy&paste impl from rustc_metadata
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for Symbol { fn encode_symbol(&mut self, symbol: Symbol) {
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
// if symbol preinterned, emit tag and symbol index // if symbol preinterned, emit tag and symbol index
if self.is_preinterned() { if symbol.is_preinterned() {
s.encoder.emit_u8(SYMBOL_PREINTERNED); self.encoder.emit_u8(SYMBOL_PREINTERNED);
s.encoder.emit_u32(self.as_u32()); self.encoder.emit_u32(symbol.as_u32());
} else { } else {
// otherwise write it as string or as offset to it // otherwise write it as string or as offset to it
match s.symbol_table.entry(*self) { match self.symbol_table.entry(symbol) {
Entry::Vacant(o) => { Entry::Vacant(o) => {
s.encoder.emit_u8(SYMBOL_STR); self.encoder.emit_u8(SYMBOL_STR);
let pos = s.encoder.position(); let pos = self.encoder.position();
o.insert(pos); o.insert(pos);
s.emit_str(self.as_str()); self.emit_str(symbol.as_str());
} }
Entry::Occupied(o) => { Entry::Occupied(o) => {
let x = *o.get(); let x = *o.get();
s.emit_u8(SYMBOL_OFFSET); self.emit_u8(SYMBOL_OFFSET);
s.emit_usize(x); self.emit_usize(x);
} }
} }
} }
} }
fn encode_crate_num(&mut self, crate_num: CrateNum) {
self.tcx.stable_crate_id(crate_num).encode(self);
}
fn encode_def_id(&mut self, def_id: DefId) {
self.tcx.def_path_hash(def_id).encode(self);
}
fn encode_def_index(&mut self, _def_index: DefIndex) {
bug!("encoding `DefIndex` without context");
}
} }
impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> { impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
@ -967,26 +959,6 @@ impl<'a, 'tcx> TyEncoder for CacheEncoder<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for CrateNum {
#[inline]
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
s.tcx.stable_crate_id(*self).encode(s);
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for DefId {
#[inline]
fn encode(&self, s: &mut CacheEncoder<'a, 'tcx>) {
s.tcx.def_path_hash(*self).encode(s);
}
}
impl<'a, 'tcx> Encodable<CacheEncoder<'a, 'tcx>> for DefIndex {
fn encode(&self, _: &mut CacheEncoder<'a, 'tcx>) {
bug!("encoding `DefIndex` without context");
}
}
macro_rules! encoder_methods { macro_rules! encoder_methods {
($($name:ident($ty:ty);)*) => { ($($name:ident($ty:ty);)*) => {
#[inline] #[inline]

View File

@ -1,11 +1,11 @@
use crate::{HashStableContext, Symbol}; use crate::{HashStableContext, SpanDecoder, SpanEncoder, Symbol};
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher, ToStableHashKey};
use rustc_data_structures::unhash::Unhasher; use rustc_data_structures::unhash::Unhasher;
use rustc_data_structures::AtomicRef; use rustc_data_structures::AtomicRef;
use rustc_index::Idx; use rustc_index::Idx;
use rustc_macros::HashStable_Generic; use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use rustc_serialize::{Decodable, Encodable};
use std::fmt; use std::fmt;
use std::hash::{BuildHasherDefault, Hash, Hasher}; use std::hash::{BuildHasherDefault, Hash, Hasher};
@ -46,20 +46,6 @@ impl fmt::Display for CrateNum {
} }
} }
/// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
/// Therefore, make sure to include the context when encode a `CrateNum`.
impl<E: Encoder> Encodable<E> for CrateNum {
default fn encode(&self, s: &mut E) {
s.emit_u32(self.as_u32());
}
}
impl<D: Decoder> Decodable<D> for CrateNum {
default fn decode(d: &mut D) -> CrateNum {
CrateNum::from_u32(d.read_u32())
}
}
/// A `DefPathHash` is a fixed-size representation of a `DefPath` that is /// A `DefPathHash` is a fixed-size representation of a `DefPath` that is
/// stable across crate and compilation session boundaries. It consists of two /// stable across crate and compilation session boundaries. It consists of two
/// separate 64-bit hashes. The first uniquely identifies the crate this /// separate 64-bit hashes. The first uniquely identifies the crate this
@ -220,18 +206,6 @@ rustc_index::newtype_index! {
} }
} }
impl<E: Encoder> Encodable<E> for DefIndex {
default fn encode(&self, _: &mut E) {
panic!("cannot encode `DefIndex` with `{}`", std::any::type_name::<E>());
}
}
impl<D: Decoder> Decodable<D> for DefIndex {
default fn decode(_: &mut D) -> DefIndex {
panic!("cannot decode `DefIndex` with `{}`", std::any::type_name::<D>());
}
}
/// A `DefId` identifies a particular *definition*, by combining a crate /// A `DefId` identifies a particular *definition*, by combining a crate
/// index and a def index. /// index and a def index.
/// ///
@ -347,19 +321,6 @@ impl From<LocalDefId> for DefId {
} }
} }
impl<E: Encoder> Encodable<E> for DefId {
default fn encode(&self, s: &mut E) {
self.krate.encode(s);
self.index.encode(s);
}
}
impl<D: Decoder> Decodable<D> for DefId {
default fn decode(d: &mut D) -> DefId {
DefId { krate: Decodable::decode(d), index: Decodable::decode(d) }
}
}
pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result { pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish() f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
} }
@ -423,13 +384,13 @@ impl fmt::Debug for LocalDefId {
} }
} }
impl<E: Encoder> Encodable<E> for LocalDefId { impl<E: SpanEncoder> Encodable<E> for LocalDefId {
fn encode(&self, s: &mut E) { fn encode(&self, s: &mut E) {
self.to_def_id().encode(s); self.to_def_id().encode(s);
} }
} }
impl<D: Decoder> Decodable<D> for LocalDefId { impl<D: SpanDecoder> Decodable<D> for LocalDefId {
fn decode(d: &mut D) -> LocalDefId { fn decode(d: &mut D) -> LocalDefId {
DefId::decode(d).expect_local() DefId::decode(d).expect_local()
} }

View File

@ -27,7 +27,7 @@
use crate::def_id::{CrateNum, DefId, StableCrateId, CRATE_DEF_ID, LOCAL_CRATE}; use crate::def_id::{CrateNum, DefId, StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
use crate::edition::Edition; use crate::edition::Edition;
use crate::symbol::{kw, sym, Symbol}; use crate::symbol::{kw, sym, Symbol};
use crate::{with_session_globals, HashStableContext, Span, DUMMY_SP}; use crate::{with_session_globals, HashStableContext, Span, SpanDecoder, SpanEncoder, DUMMY_SP};
use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{Hash64, HashStable, HashingControls, StableHasher}; use rustc_data_structures::stable_hasher::{Hash64, HashStable, HashingControls, StableHasher};
@ -1431,30 +1431,18 @@ fn for_all_expns_in(
} }
} }
impl<E: Encoder> Encodable<E> for LocalExpnId { impl<E: SpanEncoder> Encodable<E> for LocalExpnId {
fn encode(&self, e: &mut E) { fn encode(&self, e: &mut E) {
self.to_expn_id().encode(e); self.to_expn_id().encode(e);
} }
} }
impl<E: Encoder> Encodable<E> for ExpnId { impl<D: SpanDecoder> Decodable<D> for LocalExpnId {
default fn encode(&self, _: &mut E) {
panic!("cannot encode `ExpnId` with `{}`", std::any::type_name::<E>());
}
}
impl<D: Decoder> Decodable<D> for LocalExpnId {
fn decode(d: &mut D) -> Self { fn decode(d: &mut D) -> Self {
ExpnId::expect_local(ExpnId::decode(d)) ExpnId::expect_local(ExpnId::decode(d))
} }
} }
impl<D: Decoder> Decodable<D> for ExpnId {
default fn decode(_: &mut D) -> Self {
panic!("cannot decode `ExpnId` with `{}`", std::any::type_name::<D>());
}
}
pub fn raw_encode_syntax_context<E: Encoder>( pub fn raw_encode_syntax_context<E: Encoder>(
ctxt: SyntaxContext, ctxt: SyntaxContext,
context: &HygieneEncodeContext, context: &HygieneEncodeContext,
@ -1466,18 +1454,6 @@ pub fn raw_encode_syntax_context<E: Encoder>(
ctxt.0.encode(e); ctxt.0.encode(e);
} }
impl<E: Encoder> Encodable<E> for SyntaxContext {
default fn encode(&self, _: &mut E) {
panic!("cannot encode `SyntaxContext` with `{}`", std::any::type_name::<E>());
}
}
impl<D: Decoder> Decodable<D> for SyntaxContext {
default fn decode(_: &mut D) -> Self {
panic!("cannot decode `SyntaxContext` with `{}`", std::any::type_name::<D>());
}
}
/// Updates the `disambiguator` field of the corresponding `ExpnData` /// Updates the `disambiguator` field of the corresponding `ExpnData`
/// such that the `Fingerprint` of the `ExpnData` does not collide with /// such that the `Fingerprint` of the `ExpnData` does not collide with
/// any other `ExpnIds`. /// any other `ExpnIds`.

View File

@ -61,7 +61,7 @@ pub use hygiene::{DesugaringKind, ExpnKind, MacroKind};
pub use hygiene::{ExpnData, ExpnHash, ExpnId, LocalExpnId, SyntaxContext}; pub use hygiene::{ExpnData, ExpnHash, ExpnId, LocalExpnId, SyntaxContext};
use rustc_data_structures::stable_hasher::HashingControls; use rustc_data_structures::stable_hasher::HashingControls;
pub mod def_id; pub mod def_id;
use def_id::{CrateNum, DefId, DefPathHash, LocalDefId, StableCrateId, LOCAL_CRATE}; use def_id::{CrateNum, DefId, DefIndex, DefPathHash, LocalDefId, StableCrateId, LOCAL_CRATE};
pub mod edit_distance; pub mod edit_distance;
mod span_encoding; mod span_encoding;
pub use span_encoding::{Span, DUMMY_SP}; pub use span_encoding::{Span, DUMMY_SP};
@ -1021,6 +1021,14 @@ impl Default for Span {
pub trait SpanEncoder: Encoder { pub trait SpanEncoder: Encoder {
fn encode_span(&mut self, span: Span); fn encode_span(&mut self, span: Span);
fn encode_symbol(&mut self, symbol: Symbol);
fn encode_expn_id(&mut self, expn_id: ExpnId);
fn encode_syntax_context(&mut self, syntax_context: SyntaxContext);
/// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
/// Therefore, make sure to include the context when encode a `CrateNum`.
fn encode_crate_num(&mut self, crate_num: CrateNum);
fn encode_def_index(&mut self, def_index: DefIndex);
fn encode_def_id(&mut self, def_id: DefId);
} }
impl SpanEncoder for FileEncoder { impl SpanEncoder for FileEncoder {
@ -1029,6 +1037,31 @@ impl SpanEncoder for FileEncoder {
span.lo.encode(self); span.lo.encode(self);
span.hi.encode(self); span.hi.encode(self);
} }
fn encode_symbol(&mut self, symbol: Symbol) {
self.emit_str(symbol.as_str());
}
fn encode_expn_id(&mut self, _expn_id: ExpnId) {
panic!("cannot encode `ExpnId` with `FileEncoder`");
}
fn encode_syntax_context(&mut self, _syntax_context: SyntaxContext) {
panic!("cannot encode `SyntaxContext` with `FileEncoder`");
}
fn encode_crate_num(&mut self, crate_num: CrateNum) {
self.emit_u32(crate_num.as_u32());
}
fn encode_def_index(&mut self, _def_index: DefIndex) {
panic!("cannot encode `DefIndex` with `FileEncoder`");
}
fn encode_def_id(&mut self, def_id: DefId) {
def_id.krate.encode(self);
def_id.index.encode(self);
}
} }
impl<E: SpanEncoder> Encodable<E> for Span { impl<E: SpanEncoder> Encodable<E> for Span {
@ -1037,8 +1070,50 @@ impl<E: SpanEncoder> Encodable<E> for Span {
} }
} }
impl<E: SpanEncoder> Encodable<E> for Symbol {
fn encode(&self, s: &mut E) {
s.encode_symbol(*self);
}
}
impl<E: SpanEncoder> Encodable<E> for ExpnId {
fn encode(&self, s: &mut E) {
s.encode_expn_id(*self)
}
}
impl<E: SpanEncoder> Encodable<E> for SyntaxContext {
fn encode(&self, s: &mut E) {
s.encode_syntax_context(*self)
}
}
impl<E: SpanEncoder> Encodable<E> for CrateNum {
fn encode(&self, s: &mut E) {
s.encode_crate_num(*self)
}
}
impl<E: SpanEncoder> Encodable<E> for DefIndex {
fn encode(&self, s: &mut E) {
s.encode_def_index(*self)
}
}
impl<E: SpanEncoder> Encodable<E> for DefId {
fn encode(&self, s: &mut E) {
s.encode_def_id(*self)
}
}
pub trait SpanDecoder: Decoder { pub trait SpanDecoder: Decoder {
fn decode_span(&mut self) -> Span; fn decode_span(&mut self) -> Span;
fn decode_symbol(&mut self) -> Symbol;
fn decode_expn_id(&mut self) -> ExpnId;
fn decode_syntax_context(&mut self) -> SyntaxContext;
fn decode_crate_num(&mut self) -> CrateNum;
fn decode_def_index(&mut self) -> DefIndex;
fn decode_def_id(&mut self) -> DefId;
} }
impl SpanDecoder for MemDecoder<'_> { impl SpanDecoder for MemDecoder<'_> {
@ -1048,6 +1123,30 @@ impl SpanDecoder for MemDecoder<'_> {
Span::new(lo, hi, SyntaxContext::root(), None) Span::new(lo, hi, SyntaxContext::root(), None)
} }
fn decode_symbol(&mut self) -> Symbol {
Symbol::intern(self.read_str())
}
fn decode_expn_id(&mut self) -> ExpnId {
panic!("cannot decode `ExpnId` with `MemDecoder`");
}
fn decode_syntax_context(&mut self) -> SyntaxContext {
panic!("cannot decode `SyntaxContext` with `MemDecoder`");
}
fn decode_crate_num(&mut self) -> CrateNum {
CrateNum::from_u32(self.read_u32())
}
fn decode_def_index(&mut self) -> DefIndex {
panic!("cannot decode `DefIndex` with `MemDecoder`");
}
fn decode_def_id(&mut self) -> DefId {
DefId { krate: Decodable::decode(self), index: Decodable::decode(self) }
}
} }
impl<D: SpanDecoder> Decodable<D> for Span { impl<D: SpanDecoder> Decodable<D> for Span {
@ -1056,6 +1155,42 @@ impl<D: SpanDecoder> Decodable<D> for Span {
} }
} }
impl<D: SpanDecoder> Decodable<D> for Symbol {
fn decode(s: &mut D) -> Symbol {
s.decode_symbol()
}
}
impl<D: SpanDecoder> Decodable<D> for ExpnId {
fn decode(s: &mut D) -> ExpnId {
s.decode_expn_id()
}
}
impl<D: SpanDecoder> Decodable<D> for SyntaxContext {
fn decode(s: &mut D) -> SyntaxContext {
s.decode_syntax_context()
}
}
impl<D: SpanDecoder> Decodable<D> for CrateNum {
fn decode(s: &mut D) -> CrateNum {
s.decode_crate_num()
}
}
impl<D: SpanDecoder> Decodable<D> for DefIndex {
fn decode(s: &mut D) -> DefIndex {
s.decode_def_index()
}
}
impl<D: SpanDecoder> Decodable<D> for DefId {
fn decode(s: &mut D) -> DefId {
s.decode_def_id()
}
}
/// Insert `source_map` into the session globals for the duration of the /// Insert `source_map` into the session globals for the duration of the
/// closure's execution. /// closure's execution.
pub fn set_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T { pub fn set_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {

View File

@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_data_structures::sync::Lock; use rustc_data_structures::sync::Lock;
use rustc_macros::HashStable_Generic; use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::fmt; use std::fmt;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
@ -2075,19 +2074,6 @@ impl ToString for Symbol {
} }
} }
impl<S: Encoder> Encodable<S> for Symbol {
default fn encode(&self, s: &mut S) {
s.emit_str(self.as_str());
}
}
impl<D: Decoder> Decodable<D> for Symbol {
#[inline]
default fn decode(d: &mut D) -> Symbol {
Symbol::intern(d.read_str())
}
}
impl<CTX> HashStable<CTX> for Symbol { impl<CTX> HashStable<CTX> for Symbol {
#[inline] #[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) { fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {