1
Fork 0

Auto merge of #119478 - bjorn3:no_serialize_specialization, r=wesleywiser

Avoid specialization in the metadata serialization code

With the exception of a perf-only specialization for byte slices and byte vectors.

This uses the same trick of introducing a new trait and having the Encodable and Decodable derives add a bound to it as used for TyEncoder/TyDecoder. The new code is clearer about which encoder/decoder uses which impl and it reduces the dependency of rustc on specialization, making it easier to remove support for specialization entirely or turn it into a construct that is only allowed for perf optimizations if we decide to do this.
This commit is contained in:
bors 2024-01-06 09:56:00 +00:00
commit e21f4cd98f
24 changed files with 478 additions and 400 deletions

View file

@ -1,4 +1,4 @@
use crate::{HashStableContext, Symbol};
use crate::{HashStableContext, SpanDecoder, SpanEncoder, Symbol};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{
Hash64, HashStable, StableHasher, StableOrd, ToStableHashKey,
@ -7,7 +7,7 @@ use rustc_data_structures::unhash::Unhasher;
use rustc_data_structures::AtomicRef;
use rustc_index::Idx;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_serialize::{Decodable, Encodable};
use std::fmt;
use std::hash::{BuildHasherDefault, Hash, Hasher};
@ -48,20 +48,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
/// stable across crate and compilation session boundaries. It consists of two
/// separate 64-bit hashes. The first uniquely identifies the crate this
@ -227,18 +213,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
/// index and a def index.
///
@ -354,19 +328,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 {
f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
}
@ -430,13 +391,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) {
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 {
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::edition::Edition;
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::fx::{FxHashMap, FxHashSet};
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) {
self.to_expn_id().encode(e);
}
}
impl<E: Encoder> Encodable<E> for ExpnId {
default fn encode(&self, _: &mut E) {
panic!("cannot encode `ExpnId` with `{}`", std::any::type_name::<E>());
}
}
impl<D: Decoder> Decodable<D> for LocalExpnId {
impl<D: SpanDecoder> Decodable<D> for LocalExpnId {
fn decode(d: &mut D) -> Self {
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>(
ctxt: SyntaxContext,
context: &HygieneEncodeContext,
@ -1466,18 +1454,6 @@ pub fn raw_encode_syntax_context<E: Encoder>(
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`
/// such that the `Fingerprint` of the `ExpnData` does not collide with
/// any other `ExpnIds`.

View file

@ -35,6 +35,8 @@
#![feature(rustdoc_internals)]
// tidy-alphabetical-end
extern crate self as rustc_span;
#[macro_use]
extern crate rustc_macros;
@ -43,6 +45,7 @@ extern crate tracing;
use rustc_data_structures::{outline, AtomicRef};
use rustc_macros::HashStable_Generic;
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
mod caching_source_map_view;
@ -58,7 +61,7 @@ pub use hygiene::{DesugaringKind, ExpnKind, MacroKind};
pub use hygiene::{ExpnData, ExpnHash, ExpnId, LocalExpnId, SyntaxContext};
use rustc_data_structures::stable_hasher::HashingControls;
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;
mod span_encoding;
pub use span_encoding::{Span, DUMMY_SP};
@ -1016,20 +1019,203 @@ impl Default for Span {
}
}
impl<E: Encoder> Encodable<E> for Span {
default fn encode(&self, s: &mut E) {
let span = self.data();
span.lo.encode(s);
span.hi.encode(s);
rustc_index::newtype_index! {
#[orderable]
#[debug_format = "AttrId({})"]
pub struct AttrId {}
}
/// This trait is used to allow encoder specific encodings of certain types.
/// It is similar to rustc_type_ir's TyEncoder.
pub trait SpanEncoder: Encoder {
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 {
fn encode_span(&mut self, span: Span) {
let span = span.data();
span.lo.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<D: Decoder> Decodable<D> for Span {
default fn decode(s: &mut D) -> Span {
let lo = Decodable::decode(s);
let hi = Decodable::decode(s);
impl<E: SpanEncoder> Encodable<E> for Span {
fn encode(&self, s: &mut E) {
s.encode_span(*self);
}
}
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)
}
}
impl<E: SpanEncoder> Encodable<E> for AttrId {
fn encode(&self, _s: &mut E) {
// A fresh id will be generated when decoding
}
}
/// This trait is used to allow decoder specific encodings of certain types.
/// It is similar to rustc_type_ir's TyDecoder.
pub trait SpanDecoder: Decoder {
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;
fn decode_attr_id(&mut self) -> AttrId;
}
impl SpanDecoder for MemDecoder<'_> {
fn decode_span(&mut self) -> Span {
let lo = Decodable::decode(self);
let hi = Decodable::decode(self);
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) }
}
fn decode_attr_id(&mut self) -> AttrId {
panic!("cannot decode `AttrId` with `MemDecoder`");
}
}
impl<D: SpanDecoder> Decodable<D> for Span {
fn decode(s: &mut D) -> Span {
s.decode_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()
}
}
impl<D: SpanDecoder> Decodable<D> for AttrId {
fn decode(s: &mut D) -> AttrId {
s.decode_attr_id()
}
}
/// Insert `source_map` into the session globals for the duration of the
@ -1360,7 +1546,7 @@ impl Clone for SourceFile {
}
}
impl<S: Encoder> Encodable<S> for SourceFile {
impl<S: SpanEncoder> Encodable<S> for SourceFile {
fn encode(&self, s: &mut S) {
self.name.encode(s);
self.src_hash.encode(s);
@ -1434,7 +1620,7 @@ impl<S: Encoder> Encodable<S> for SourceFile {
}
}
impl<D: Decoder> Decodable<D> for SourceFile {
impl<D: SpanDecoder> Decodable<D> for SourceFile {
fn decode(d: &mut D) -> SourceFile {
let name: FileName = Decodable::decode(d);
let src_hash: SourceFileHash = Decodable::decode(d);

View file

@ -9,7 +9,6 @@ use rustc_data_structures::stable_hasher::{
};
use rustc_data_structures::sync::Lock;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::fmt;
use std::hash::{Hash, Hasher};
@ -2078,19 +2077,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 {
#[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {