split out blob decode trait

This commit is contained in:
Jana Dönszelmann 2025-11-27 12:21:35 +01:00
parent ba2142a19c
commit f8bbf2ca06
No known key found for this signature in database
23 changed files with 331 additions and 203 deletions

View file

@ -11,7 +11,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::unord::UnordMap;
use rustc_hashes::Hash64;
use rustc_index::IndexVec;
use rustc_macros::{Decodable, Encodable};
use rustc_macros::{BlobDecodable, Decodable, Encodable};
use rustc_span::{Symbol, kw, sym};
use tracing::{debug, instrument};
@ -127,7 +127,7 @@ pub struct Definitions {
/// A unique identifier that we can use to lookup a definition
/// precisely. It combines the index of the definition's parent (if
/// any) with a `DisambiguatedDefPathData`.
#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)]
#[derive(Copy, Clone, PartialEq, Debug, Encodable, BlobDecodable)]
pub struct DefKey {
/// The parent path.
pub parent: Option<DefIndex>,
@ -176,7 +176,7 @@ impl DefKey {
/// between them. This introduces some artificial ordering dependency
/// but means that if you have, e.g., two impls for the same type in
/// the same module, they do get distinct `DefId`s.
#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)]
#[derive(Copy, Clone, PartialEq, Debug, Encodable, BlobDecodable)]
pub struct DisambiguatedDefPathData {
pub data: DefPathData,
pub disambiguator: u32,
@ -270,7 +270,7 @@ impl DefPath {
}
/// New variants should only be added in synchronization with `enum DefKind`.
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, BlobDecodable)]
pub enum DefPathData {
// Root: these should only be used for the root nodes, because
// they are treated specially by the `def_path` function.

View file

@ -10,7 +10,7 @@
use rustc_ast::attr::AttributeExt;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_macros::{BlobDecodable, Encodable, HashStable_Generic};
use rustc_span::{Span, Symbol, kw, sym};
use crate::def_id::DefId;
@ -75,7 +75,7 @@ macro_rules! language_item_table {
$( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
) => {
/// A representation of all the valid lang items in Rust.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, BlobDecodable)]
pub enum LangItem {
$(
#[doc = concat!("The `", stringify!($name), "` lang item.")]

View file

@ -1,6 +1,6 @@
use std::num::NonZero;
use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic, PrintAttribute};
use rustc_span::{ErrorGuaranteed, Symbol, sym};
use crate::RustcVersion;
@ -21,7 +21,7 @@ pub const VERSION_PLACEHOLDER: &str = concat!("CURRENT_RUSTC_VERSIO", "N");
///
/// - `#[stable]`
/// - `#[unstable]`
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(Encodable, BlobDecodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable_Generic, PrintAttribute)]
pub struct Stability {
pub level: StabilityLevel,
@ -103,7 +103,7 @@ impl PartialConstStability {
}
/// The available stability levels.
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(HashStable_Generic, PrintAttribute)]
pub enum StabilityLevel {
/// `#[unstable]`
@ -146,7 +146,7 @@ pub enum StabilityLevel {
}
/// Rust release in which a feature is stabilized.
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)]
#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)]
#[derive(HashStable_Generic, PrintAttribute)]
pub enum StableSince {
/// also stores the original symbol for printing
@ -172,7 +172,7 @@ impl StabilityLevel {
}
}
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(Encodable, BlobDecodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(HashStable_Generic, PrintAttribute)]
pub enum UnstableReason {
None,

View file

@ -4,12 +4,12 @@ use std::sync::OnceLock;
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
use rustc_macros::{
Decodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version,
BlobDecodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version,
};
use crate::attrs::PrintAttribute;
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Encodable, BlobDecodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(HashStable_Generic, PrintAttribute)]
pub struct RustcVersion {
pub major: u16,

View file

@ -78,7 +78,18 @@ decl_derive!([Decodable] => serialize::decodable_derive);
decl_derive!([Encodable] => serialize::encodable_derive);
decl_derive!([TyDecodable] => serialize::type_decodable_derive);
decl_derive!([TyEncodable] => serialize::type_encodable_derive);
decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive);
decl_derive!([MetadataDecodable] =>
/// This constrains the decoder to be specifically the decoder that can decode LazyArrays in metadata.
/// Therefore, we only use this on things containing LazyArray really.
/// Anything else should either be `NoContext`, if possible `BlobDecodable`, or otherwise just `Decodable`.
serialize::meta_decodable_derive
);
decl_derive!([BlobDecodable] =>
/// For anything that is "simple" to decode, without needing anything but the original data,
/// but for which the Decoder can customize some things
/// (unlike Decodable_NoContext which individual decoders can't customize).
serialize::blob_decodable_derive
);
decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive);
decl_derive!(
[TypeFoldable, attributes(type_foldable)] =>

View file

@ -16,14 +16,21 @@ pub(super) fn type_decodable_derive(
decodable_body(s, decoder_ty)
}
pub(super) fn blob_decodable_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
let decoder_ty = quote! { __D };
s.add_impl_generic(parse_quote! { #decoder_ty: ::rustc_span::BlobDecoder });
s.add_bounds(synstructure::AddBounds::Generics);
decodable_body(s, decoder_ty)
}
pub(super) fn meta_decodable_derive(
mut s: synstructure::Structure<'_>,
) -> proc_macro2::TokenStream {
if !s.ast().generics.lifetimes().any(|lt| lt.lifetime.ident == "tcx") {
s.add_impl_generic(parse_quote! { 'tcx });
}
s.add_impl_generic(parse_quote! { '__a });
let decoder_ty = quote! { DecodeContext<'__a, 'tcx> };
let decoder_ty = quote! { __D };
s.add_impl_generic(parse_quote! { #decoder_ty: LazyDecoder });
s.add_bounds(synstructure::AddBounds::Generics);
decodable_body(s, decoder_ty)

View file

@ -224,6 +224,7 @@ use rustc_data_structures::owned_slice::{OwnedSlice, slice_owned};
use rustc_data_structures::svh::Svh;
use rustc_errors::{DiagArgValue, IntoDiagArg};
use rustc_fs_util::try_canonicalize;
use rustc_middle::ty::TyCtxt;
use rustc_session::cstore::CrateSource;
use rustc_session::filesearch::FileSearch;
use rustc_session::search_paths::PathKind;

View file

@ -1,6 +1,7 @@
// Decoding metadata from a single crate's metadata
use std::iter::TrustedLen;
use std::ops::{Deref, DerefMut};
use std::path::{Path, PathBuf};
use std::sync::{Arc, OnceLock};
use std::{io, mem};
@ -33,7 +34,8 @@ use rustc_session::config::TargetModifier;
use rustc_session::cstore::{CrateSource, ExternCrate};
use rustc_span::hygiene::HygieneDecodeContext;
use rustc_span::{
BytePos, ByteSymbol, DUMMY_SP, Pos, SpanData, SpanDecoder, Symbol, SyntaxContext, kw,
BlobDecoder, BytePos, ByteSymbol, DUMMY_SP, Pos, SpanData, SpanDecoder, Symbol, SyntaxContext,
kw,
};
use tracing::debug;
@ -154,22 +156,106 @@ struct ImportedSourceFile {
translated_source_file: Arc<rustc_span::SourceFile>,
}
pub(super) struct DecodeContext<'a, 'tcx> {
/// Decode context used when we just have a blob,
/// and we still have to read the header etc.
pub(super) struct BlobDecodeContext<'a> {
opaque: MemDecoder<'a>,
cdata: Option<CrateMetadataRef<'a>>,
blob: &'a MetadataBlob,
lazy_state: LazyState,
}
/// trait for anything containing `LazyState` and is a decoder.
// TODO: might need to live in rustc_middle
pub(super) trait LazyDecoder: BlobDecoder {
fn set_lazy_state(&mut self, state: LazyState);
fn get_lazy_state(&self) -> LazyState;
fn read_lazy<T>(&mut self) -> LazyValue<T> {
self.read_lazy_offset_then(|pos| LazyValue::from_position(pos))
}
fn read_lazy_array<T>(&mut self, len: usize) -> LazyArray<T> {
self.read_lazy_offset_then(|pos| LazyArray::from_position_and_num_elems(pos, len))
}
fn read_lazy_table<I, T>(&mut self, width: usize, len: usize) -> LazyTable<I, T> {
self.read_lazy_offset_then(|pos| LazyTable::from_position_and_encoded_size(pos, width, len))
}
#[inline]
fn read_lazy_offset_then<T>(&mut self, f: impl Fn(NonZero<usize>) -> T) -> T {
let distance = self.read_usize();
let position = match self.get_lazy_state() {
LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
LazyState::NodeStart(start) => {
let start = start.get();
assert!(distance <= start);
start - distance
}
LazyState::Previous(last_pos) => last_pos.get() + distance,
};
let position = NonZero::new(position).unwrap();
self.set_lazy_state(LazyState::Previous(position));
f(position)
}
}
impl<'a> LazyDecoder for BlobDecodeContext<'a> {
fn set_lazy_state(&mut self, state: LazyState) {
self.lazy_state = state;
}
fn get_lazy_state(&self) -> LazyState {
self.lazy_state
}
}
/// This is the decode context used when crate metadata was already read.
/// Decoding of some types, like `Span` require some information to already been read.
pub(super) struct MetadataDecodeContext<'a, 'tcx> {
blob_decoder: BlobDecodeContext<'a>,
cdata: Option<CrateMetadataRef<'a>>,
sess: Option<&'tcx Session>,
tcx: Option<TyCtxt<'tcx>>,
lazy_state: LazyState,
// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
alloc_decoding_session: Option<AllocDecodingSession<'a>>,
}
impl<'a, 'tcx> LazyDecoder for MetadataDecodeContext<'a, 'tcx> {
fn set_lazy_state(&mut self, state: LazyState) {
self.lazy_state = state;
}
fn get_lazy_state(&self) -> LazyState {
self.lazy_state
}
}
impl<'a, 'tcx> DerefMut for MetadataDecodeContext<'a, 'tcx> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.blob_decoder
}
}
impl<'a, 'tcx> Deref for MetadataDecodeContext<'a, 'tcx> {
type Target = BlobDecodeContext<'a>;
fn deref(&self) -> &Self::Target {
&self.blob_decoder
}
}
pub(super) trait BlobMetadata<'a, 'tcx>: Copy {
type Context: BlobDecoder + LazyDecoder;
fn blob(self) -> &'a MetadataBlob;
fn decoder(self, pos: usize) -> Self::Context;
}
/// Abstract over the various ways one can create metadata decoders.
pub(super) trait Metadata<'a, 'tcx>: Copy {
fn blob(self) -> &'a MetadataBlob;
fn _blob(self) -> &'a MetadataBlob;
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
None
@ -180,23 +266,25 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
fn tcx(self) -> Option<TyCtxt<'tcx>> {
None
}
}
fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> {
impl<'a, 'tcx, T> BlobMetadata<'a, 'tcx> for T
where
T: Metadata<'a, 'tcx>,
{
type Context = MetadataDecodeContext<'a, 'tcx>;
fn blob(self) -> &'a MetadataBlob {
self._blob()
}
fn decoder(self, pos: usize) -> MetadataDecodeContext<'a, 'tcx> {
let tcx = self.tcx();
DecodeContext {
// FIXME: This unwrap should never panic because we check that it won't when creating
// `MetadataBlob`. Ideally we'd just have a `MetadataDecoder` and hand out subslices of
// it as we do elsewhere in the compiler using `MetadataDecoder::split_at`. But we own
// the data for the decoder so holding onto the `MemDecoder` too would make us a
// self-referential struct which is downright goofy because `MetadataBlob` is already
// self-referential. Probably `MemDecoder` should contain an `OwnedSlice`, but that
// demands a significant refactoring due to our crate graph.
opaque: MemDecoder::new(self.blob(), pos).unwrap(),
MetadataDecodeContext {
blob_decoder: self.blob().decoder(pos),
cdata: self.cdata(),
blob: self.blob(),
sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
tcx,
lazy_state: LazyState::NoNode,
alloc_decoding_session: self
.cdata()
.map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()),
@ -204,16 +292,32 @@ pub(super) trait Metadata<'a, 'tcx>: Copy {
}
}
impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
#[inline]
impl<'a, 'tcx> BlobMetadata<'a, 'tcx> for &'a MetadataBlob {
type Context = BlobDecodeContext<'a>;
fn blob(self) -> &'a MetadataBlob {
self
}
fn decoder(self, pos: usize) -> Self::Context {
BlobDecodeContext {
// FIXME: This unwrap should never panic because we check that it won't when creating
// `MetadataBlob`. Ideally we'd just have a `MetadataDecoder` and hand out subslices of
// it as we do elsewhere in the compiler using `MetadataDecoder::split_at`. But we own
// the data for the decoder so holding onto the `MemDecoder` too would make us a
// self-referential struct which is downright goofy because `MetadataBlob` is already
// self-referential. Probably `MemDecoder` should contain an `OwnedSlice`, but that
// demands a significant refactoring due to our crate graph.
opaque: MemDecoder::new(self, pos).unwrap(),
lazy_state: LazyState::NoNode,
blob: self.blob(),
}
}
}
impl<'a, 'tcx> Metadata<'a, 'tcx> for CrateMetadataRef<'a> {
#[inline]
fn blob(self) -> &'a MetadataBlob {
fn _blob(self) -> &'a MetadataBlob {
&self.cdata.blob
}
#[inline]
@ -224,7 +328,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for CrateMetadataRef<'a> {
impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, &'tcx Session) {
#[inline]
fn blob(self) -> &'a MetadataBlob {
fn _blob(self) -> &'a MetadataBlob {
&self.0.cdata.blob
}
#[inline]
@ -239,7 +343,7 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, &'tcx Session) {
impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) {
#[inline]
fn blob(self) -> &'a MetadataBlob {
fn _blob(self) -> &'a MetadataBlob {
&self.0.cdata.blob
}
#[inline]
@ -254,23 +358,23 @@ impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) {
impl<T: ParameterizedOverTcx> LazyValue<T> {
#[inline]
fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx>
fn decode<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx>
where
T::Value<'tcx>: Decodable<DecodeContext<'a, 'tcx>>,
T::Value<'tcx>: Decodable<M::Context>,
{
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
dcx.set_lazy_state(LazyState::NodeStart(self.position));
T::Value::decode(&mut dcx)
}
}
struct DecodeIterator<'a, 'tcx, T> {
struct DecodeIterator<T, D> {
elem_counter: std::ops::Range<usize>,
dcx: DecodeContext<'a, 'tcx>,
dcx: D,
_phantom: PhantomData<fn() -> T>,
}
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Iterator for DecodeIterator<'a, 'tcx, T> {
impl<D: Decoder, T: Decodable<D>> Iterator for DecodeIterator<T, D> {
type Item = T;
#[inline(always)]
@ -284,35 +388,30 @@ impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Iterator for DecodeIterato
}
}
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> ExactSizeIterator
for DecodeIterator<'a, 'tcx, T>
{
impl<D: Decoder, T: Decodable<D>> ExactSizeIterator for DecodeIterator<T, D> {
fn len(&self) -> usize {
self.elem_counter.len()
}
}
unsafe impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> TrustedLen
for DecodeIterator<'a, 'tcx, T>
{
}
unsafe impl<D: Decoder, T: Decodable<D>> TrustedLen for DecodeIterator<T, D> {}
impl<T: ParameterizedOverTcx> LazyArray<T> {
#[inline]
fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(
fn decode<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>(
self,
metadata: M,
) -> DecodeIterator<'a, 'tcx, T::Value<'tcx>>
) -> DecodeIterator<T::Value<'tcx>, M::Context>
where
T::Value<'tcx>: Decodable<DecodeContext<'a, 'tcx>>,
T::Value<'tcx>: Decodable<M::Context>,
{
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
dcx.set_lazy_state(LazyState::NodeStart(self.position));
DecodeIterator { elem_counter: (0..self.num_elems), dcx, _phantom: PhantomData }
}
}
impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
impl<'a, 'tcx> MetadataDecodeContext<'a, 'tcx> {
#[inline]
fn tcx(&self) -> TyCtxt<'tcx> {
let Some(tcx) = self.tcx else {
@ -324,11 +423,6 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
tcx
}
#[inline]
pub(crate) fn blob(&self) -> &'a MetadataBlob {
self.blob
}
#[inline]
fn cdata(&self) -> CrateMetadataRef<'a> {
debug_assert!(self.cdata.is_some(), "missing CrateMetadata in DecodeContext");
@ -339,34 +433,12 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
self.cdata().map_encoded_cnum_to_current(cnum)
}
}
impl<'a> BlobDecodeContext<'a> {
#[inline]
fn read_lazy_offset_then<T>(&mut self, f: impl Fn(NonZero<usize>) -> T) -> T {
let distance = self.read_usize();
let position = match self.lazy_state {
LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
LazyState::NodeStart(start) => {
let start = start.get();
assert!(distance <= start);
start - distance
}
LazyState::Previous(last_pos) => last_pos.get() + distance,
};
let position = NonZero::new(position).unwrap();
self.lazy_state = LazyState::Previous(position);
f(position)
}
fn read_lazy<T>(&mut self) -> LazyValue<T> {
self.read_lazy_offset_then(|pos| LazyValue::from_position(pos))
}
fn read_lazy_array<T>(&mut self, len: usize) -> LazyArray<T> {
self.read_lazy_offset_then(|pos| LazyArray::from_position_and_num_elems(pos, len))
}
fn read_lazy_table<I, T>(&mut self, width: usize, len: usize) -> LazyTable<I, T> {
self.read_lazy_offset_then(|pos| LazyTable::from_position_and_encoded_size(pos, width, len))
pub(crate) fn blob(&self) -> &'a MetadataBlob {
self.blob
}
#[inline]
@ -397,7 +469,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
}
}
impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
impl<'a, 'tcx> TyDecoder<'tcx> for MetadataDecodeContext<'a, 'tcx> {
const CLEAR_CROSS_CRATE: bool = true;
#[inline]
@ -426,12 +498,12 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
where
F: FnOnce(&mut Self) -> R,
{
let new_opaque = self.opaque.split_at(pos);
let old_opaque = mem::replace(&mut self.opaque, new_opaque);
let old_state = mem::replace(&mut self.lazy_state, LazyState::NoNode);
let new_opaque = self.blob_decoder.opaque.split_at(pos);
let old_opaque = mem::replace(&mut self.blob_decoder.opaque, new_opaque);
let old_state = mem::replace(&mut self.blob_decoder.lazy_state, LazyState::NoNode);
let r = f(self);
self.opaque = old_opaque;
self.lazy_state = old_state;
self.blob_decoder.opaque = old_opaque;
self.blob_decoder.lazy_state = old_state;
r
}
@ -444,14 +516,14 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnIndex {
impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for ExpnIndex {
#[inline]
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ExpnIndex {
fn decode(d: &mut MetadataDecodeContext<'a, 'tcx>) -> ExpnIndex {
ExpnIndex::from_u32(d.read_u32())
}
}
impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> {
fn decode_attr_id(&mut self) -> rustc_span::AttrId {
let sess = self.sess.expect("can't decode AttrId without Session");
sess.psess.attr_id_generator.mk_attr_id()
@ -462,10 +534,6 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
self.map_encoded_cnum_to_current(cnum)
}
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) }
}
@ -554,7 +622,25 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
};
data.span()
}
}
impl<'a, 'tcx> BlobDecoder for MetadataDecodeContext<'a, 'tcx> {
fn decode_def_index(&mut self) -> DefIndex {
self.blob_decoder.decode_def_index()
}
fn decode_symbol(&mut self) -> Symbol {
self.blob_decoder.decode_symbol()
}
fn decode_byte_symbol(&mut self) -> ByteSymbol {
self.blob_decoder.decode_byte_symbol()
}
}
impl<'a> BlobDecoder for BlobDecodeContext<'a> {
fn decode_def_index(&mut self) -> DefIndex {
DefIndex::from_u32(self.read_u32())
}
fn decode_symbol(&mut self) -> Symbol {
self.decode_symbol_or_byte_symbol(
Symbol::new,
@ -572,8 +658,8 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SpanData {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SpanData {
impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for SpanData {
fn decode(decoder: &mut MetadataDecodeContext<'a, 'tcx>) -> SpanData {
let tag = SpanTag::decode(decoder);
let ctxt = tag.context().unwrap_or_else(|| SyntaxContext::decode(decoder));
@ -677,43 +763,50 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SpanData {
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
fn decode(d: &mut MetadataDecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
}
}
impl<'a, 'tcx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyValue<T> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
impl<D: LazyDecoder, T> Decodable<D> for LazyValue<T> {
fn decode(decoder: &mut D) -> Self {
decoder.read_lazy()
}
}
impl<'a, 'tcx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyArray<T> {
impl<D: LazyDecoder, T> Decodable<D> for LazyArray<T> {
#[inline]
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
fn decode(decoder: &mut D) -> Self {
let len = decoder.read_usize();
if len == 0 { LazyArray::default() } else { decoder.read_lazy_array(len) }
}
}
impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyTable<I, T> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
impl<I: Idx, D: LazyDecoder, T> Decodable<D> for LazyTable<I, T> {
fn decode(decoder: &mut D) -> Self {
let width = decoder.read_usize();
let len = decoder.read_usize();
decoder.read_lazy_table(width, len)
}
}
implement_ty_decoder!(DecodeContext<'a, 'tcx>);
mod meta {
use super::*;
implement_ty_decoder!(MetadataDecodeContext<'a, 'tcx>);
}
mod blob {
use super::*;
implement_ty_decoder!(BlobDecodeContext<'a>);
}
impl MetadataBlob {
pub(crate) fn check_compatibility(
&self,
cfg_version: &'static str,
) -> Result<(), Option<String>> {
if !self.blob().starts_with(METADATA_HEADER) {
if self.blob().starts_with(b"rust") {
if !self.starts_with(METADATA_HEADER) {
if self.starts_with(b"rust") {
return Err(Some("<unknown rustc version>".to_owned()));
}
return Err(None);
@ -731,7 +824,7 @@ impl MetadataBlob {
fn root_pos(&self) -> NonZero<usize> {
let offset = METADATA_HEADER.len();
let pos_bytes = self.blob()[offset..][..8].try_into().unwrap();
let pos_bytes = self[offset..][..8].try_into().unwrap();
let pos = u64::from_le_bytes(pos_bytes);
NonZero::new(pos as usize).unwrap()
}
@ -1897,11 +1990,12 @@ impl CrateMetadata {
};
// Need `CrateMetadataRef` to decode `DefId`s in simplified types.
let cref = CrateMetadataRef { cdata: &cdata, cstore };
cdata.incoherent_impls = cdata
.root
.incoherent_impls
.decode(CrateMetadataRef { cdata: &cdata, cstore })
.map(|incoherent_impls| (incoherent_impls.self_ty, incoherent_impls.impls))
.decode(cref)
.map(|incoherent_impls| (incoherent_impls.self_ty.decode(cref), incoherent_impls.impls))
.collect();
cdata

View file

@ -15,12 +15,13 @@ use rustc_middle::query::{ExternProviders, LocalCrate};
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::util::Providers;
use rustc_serialize::Decoder;
use rustc_session::cstore::{CrateStore, ExternCrate};
use rustc_session::{Session, StableCrateId};
use rustc_span::hygiene::ExpnId;
use rustc_span::{Span, Symbol, kw};
use super::{Decodable, DecodeContext, DecodeIterator};
use super::{Decodable, DecodeIterator};
use crate::creader::{CStore, LoadedMacro};
use crate::rmeta::AttrFlags;
use crate::rmeta::table::IsDefault;
@ -65,8 +66,8 @@ impl<T, E> ProcessQueryValue<'_, Result<Option<T>, E>> for Option<T> {
}
}
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>> ProcessQueryValue<'tcx, &'tcx [T]>
for Option<DecodeIterator<'a, 'tcx, T>>
impl<'tcx, D: Decoder, T: Copy + Decodable<D>> ProcessQueryValue<'tcx, &'tcx [T]>
for Option<DecodeIterator<T, D>>
{
#[inline(always)]
fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx [T] {
@ -74,8 +75,8 @@ impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>> ProcessQueryValue<'
}
}
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>>
ProcessQueryValue<'tcx, Option<&'tcx [T]>> for Option<DecodeIterator<'a, 'tcx, T>>
impl<'tcx, D: Decoder, T: Copy + Decodable<D>> ProcessQueryValue<'tcx, Option<&'tcx [T]>>
for Option<DecodeIterator<T, D>>
{
#[inline(always)]
fn process_decoded(self, tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> Option<&'tcx [T]> {

View file

@ -3,7 +3,8 @@ use rustc_hir::def_path_hash_map::{Config as HashMapConfig, DefPathHashMap};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::def_id::{DefIndex, DefPathHash};
use crate::rmeta::{DecodeContext, EncodeContext};
use crate::rmeta::EncodeContext;
use crate::rmeta::decoder::BlobDecodeContext;
pub(crate) enum DefPathHashMapRef<'tcx> {
OwnedFromMetadata(odht::HashTable<HashMapConfig, OwnedSlice>),
@ -40,8 +41,8 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for DefPathHashMapRef<'tcx> {
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static> {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> {
impl<'a> Decodable<BlobDecodeContext<'a>> for DefPathHashMapRef<'static> {
fn decode(d: &mut BlobDecodeContext<'a>) -> DefPathHashMapRef<'static> {
let len = d.read_usize();
let pos = d.position();
let o = d.blob().bytes().clone().slice(|blob| &blob[pos..pos + len]);

View file

@ -2205,7 +2205,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
.incoherent_impls
.iter()
.map(|(&simp, impls)| IncoherentImpls {
self_ty: simp,
self_ty: self.lazy(simp),
impls: self.lazy_array(impls.iter().map(|def_id| def_id.local_def_index)),
})
.collect();

View file

@ -1,8 +1,8 @@
use std::marker::PhantomData;
use std::num::NonZero;
use decoder::LazyDecoder;
pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob, TargetModifiers};
use decoder::{DecodeContext, Metadata};
use def_path_hash_map::DefPathHashMapRef;
use encoder::EncodeContext;
pub use encoder::{EncodedMetadata, encode_metadata, rendered_const};
@ -19,7 +19,8 @@ use rustc_hir::{PreciseCapturingArgKind, attrs};
use rustc_index::IndexVec;
use rustc_index::bit_set::DenseBitSet;
use rustc_macros::{
Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable, TyEncodable,
BlobDecodable, Decodable, Encodable, MetadataDecodable, MetadataEncodable, TyDecodable,
TyEncodable,
};
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
@ -201,7 +202,7 @@ pub(crate) struct ProcMacroData {
/// See #76720 for more details.
///
/// If you do modify this struct, also bump the [`METADATA_VERSION`] constant.
#[derive(MetadataEncodable, MetadataDecodable)]
#[derive(MetadataEncodable, BlobDecodable)]
pub(crate) struct CrateHeader {
pub(crate) triple: TargetTuple,
pub(crate) hash: Svh,
@ -323,7 +324,7 @@ impl RawDefId {
}
}
#[derive(Encodable, Decodable)]
#[derive(Encodable, BlobDecodable)]
pub(crate) struct CrateDep {
pub name: Symbol,
pub hash: Svh,
@ -341,7 +342,7 @@ pub(crate) struct TraitImpls {
#[derive(MetadataEncodable, MetadataDecodable)]
pub(crate) struct IncoherentImpls {
self_ty: SimplifiedType,
self_ty: LazyValue<SimplifiedType>,
impls: LazyArray<DefIndex>,
}

View file

@ -1,6 +1,7 @@
use rustc_hir::def::CtorOf;
use rustc_index::Idx;
use crate::rmeta::decoder::BlobMetadata;
use crate::rmeta::*;
pub(super) trait IsDefault: Default {
@ -522,7 +523,11 @@ where
for<'tcx> T::Value<'tcx>: FixedSizeEncoding<ByteArray = [u8; N]>,
{
/// Given the metadata, extract out the value at a particular index (if any).
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
pub(super) fn get<'a, 'tcx, M: BlobMetadata<'a, 'tcx>>(
&self,
metadata: M,
i: I,
) -> T::Value<'tcx> {
// Access past the end of the table returns a Default
if i.index() >= self.len {
return Default::default();

View file

@ -6,11 +6,11 @@ pub mod exported_symbols;
pub mod lang_items;
pub mod lib_features {
use rustc_data_structures::unord::UnordMap;
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_macros::{BlobDecodable, Encodable, HashStable};
use rustc_span::{Span, Symbol};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(HashStable, TyEncodable, TyDecodable)]
#[derive(HashStable, Encodable, BlobDecodable)]
pub enum FeatureStability {
AcceptedSince(Symbol),
Unstable { old_name: Option<Symbol> },

View file

@ -20,8 +20,8 @@ use rustc_span::hygiene::{
};
use rustc_span::source_map::Spanned;
use rustc_span::{
BytePos, ByteSymbol, CachingSourceMapView, ExpnData, ExpnHash, Pos, RelativeBytePos,
SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol,
BlobDecoder, BytePos, ByteSymbol, CachingSourceMapView, ExpnData, ExpnHash, Pos,
RelativeBytePos, SourceFile, Span, SpanDecoder, SpanEncoder, StableSourceFileId, Symbol,
};
use crate::dep_graph::{DepNodeIndex, SerializedDepNodeIndex};
@ -672,36 +672,12 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
Span::new(lo, hi, ctxt, parent)
}
fn decode_symbol(&mut self) -> Symbol {
self.decode_symbol_or_byte_symbol(
Symbol::new,
|this| Symbol::intern(this.read_str()),
|opaque| Symbol::intern(opaque.read_str()),
)
}
fn decode_byte_symbol(&mut self) -> ByteSymbol {
self.decode_symbol_or_byte_symbol(
ByteSymbol::new,
|this| ByteSymbol::intern(this.read_byte_str()),
|opaque| ByteSymbol::intern(opaque.read_byte_str()),
)
}
fn decode_crate_num(&mut self) -> CrateNum {
let stable_id = StableCrateId::decode(self);
let cnum = self.tcx.stable_crate_id_to_crate_num(stable_id);
cnum
}
// 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
// because we would not know how to transform the `DefIndex` to the current
// context.
fn decode_def_index(&mut self) -> DefIndex {
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
// compilation sessions. We use the `DefPathHash`, which is stable across
// sessions, to map the old `DefId` to the new one.
@ -725,6 +701,32 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
}
}
impl<'a, 'tcx> BlobDecoder for CacheDecoder<'a, 'tcx> {
fn decode_symbol(&mut self) -> Symbol {
self.decode_symbol_or_byte_symbol(
Symbol::new,
|this| Symbol::intern(this.read_str()),
|opaque| Symbol::intern(opaque.read_str()),
)
}
fn decode_byte_symbol(&mut self) -> ByteSymbol {
self.decode_symbol_or_byte_symbol(
ByteSymbol::new,
|this| ByteSymbol::intern(this.read_byte_str()),
|opaque| ByteSymbol::intern(opaque.read_byte_str()),
)
}
// 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
// because we would not know how to transform the `DefIndex` to the current
// context.
fn decode_def_index(&mut self) -> DefIndex {
panic!("trying to decode `DefIndex` outside the context of a `DefId`")
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId> {
#[inline]
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {

View file

@ -41,8 +41,8 @@ use rustc_hir::{LangItem, attrs as attr, find_attr};
use rustc_index::IndexVec;
use rustc_index::bit_set::BitMatrix;
use rustc_macros::{
Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable,
extension,
BlobDecodable, Decodable, Encodable, HashStable, TyDecodable, TyEncodable, TypeFoldable,
TypeVisitable, extension,
};
use rustc_query_system::ich::StableHashingContext;
use rustc_serialize::{Decodable, Encodable};
@ -264,7 +264,7 @@ impl Asyncness {
}
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)]
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, BlobDecodable, HashStable)]
pub enum Visibility<Id = LocalDefId> {
/// Visible everywhere (including in other crates).
Public,

View file

@ -21,7 +21,7 @@ use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, DiagArgValue, DiagCtxtFlags, IntoDiagArg};
use rustc_feature::UnstableFeatures;
use rustc_hashes::Hash64;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
use rustc_span::source_map::FilePathMapping;
use rustc_span::{
@ -543,7 +543,7 @@ impl SwitchWithOptPath {
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic)]
#[derive(Encodable, Decodable)]
#[derive(Encodable, BlobDecodable)]
pub enum SymbolManglingVersion {
Legacy,
V0,
@ -1521,7 +1521,7 @@ pub enum EntryFnType {
},
}
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)]
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, BlobDecodable)]
#[derive(HashStable_Generic)]
pub enum CrateType {
Executable,

View file

@ -12,7 +12,7 @@ use rustc_hir::def_id::{
CrateNum, DefId, LOCAL_CRATE, LocalDefId, StableCrateId, StableCrateIdMap,
};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
use rustc_span::{Span, Symbol};
use crate::search_paths::PathKind;
@ -36,7 +36,7 @@ impl CrateSource {
}
}
#[derive(Encodable, Decodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
#[derive(Encodable, BlobDecodable, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Debug)]
#[derive(HashStable_Generic)]
pub enum CrateDepKind {
/// A dependency that is only used for its macros.
@ -59,7 +59,7 @@ impl CrateDepKind {
}
}
#[derive(Copy, Debug, PartialEq, Clone, Encodable, Decodable, HashStable_Generic)]
#[derive(Copy, Debug, PartialEq, Clone, Encodable, BlobDecodable, HashStable_Generic)]
pub enum LinkagePreference {
RequireDynamic,
RequireStatic,

View file

@ -10,7 +10,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl};
use rustc_feature::UnstableFeatures;
use rustc_hashes::Hash64;
use rustc_macros::{Decodable, Encodable};
use rustc_macros::{BlobDecodable, Encodable};
use rustc_span::edition::Edition;
use rustc_span::{RealFileName, SourceFileHashAlgorithm};
use rustc_target::spec::{
@ -75,7 +75,7 @@ pub struct ExtendedTargetModifierInfo {
/// A recorded -Zopt_name=opt_value (or -Copt_name=opt_value)
/// which alter the ABI or effectiveness of exploit mitigations.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, BlobDecodable)]
pub struct TargetModifier {
/// Option enum value
pub opt: OptionsTargetModifiers,
@ -248,7 +248,7 @@ macro_rules! top_level_tmod_enum {
($user_value:ident){$($pout:tt)*};
) => {
#[allow(non_camel_case_types)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, Decodable)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, BlobDecodable)]
pub enum OptionsTargetModifiers {
$($variant($substruct_enum)),*
}
@ -520,7 +520,7 @@ macro_rules! tmod_enum {
($user_value:ident){$($pout:tt)*};
) => {
#[allow(non_camel_case_types)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, Decodable)]
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone, Encodable, BlobDecodable)]
pub enum $tmod_enum_name {
$($eout),*
}

View file

@ -7,7 +7,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableOrd,
use rustc_data_structures::unhash::Unhasher;
use rustc_hashes::Hash64;
use rustc_index::Idx;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
use rustc_serialize::{Decodable, Encodable};
use crate::{HashStableContext, SpanDecoder, SpanEncoder, Symbol};
@ -141,7 +141,7 @@ impl StableOrd for DefPathHash {
/// For more information on the possibility of hash collisions in rustc,
/// see the discussion in [`DefId`].
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
#[derive(Hash, HashStable_Generic, Encodable, Decodable)]
#[derive(Hash, HashStable_Generic, Encodable, BlobDecodable)]
pub struct StableCrateId(pub(crate) Hash64);
impl StableCrateId {

View file

@ -1,10 +1,10 @@
use std::fmt;
use std::str::FromStr;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_macros::{BlobDecodable, Encodable, HashStable_Generic};
/// The edition of the compiler. (See [RFC 2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md).)
#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, Decodable, Eq)]
#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, BlobDecodable, Eq)]
#[derive(HashStable_Generic)]
pub enum Edition {
// When adding new editions, be sure to do the following:

View file

@ -1296,20 +1296,37 @@ impl<E: SpanEncoder> Encodable<E> for AttrId {
}
}
/// 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;
pub trait BlobDecoder: Decoder {
fn decode_symbol(&mut self) -> Symbol;
fn decode_byte_symbol(&mut self) -> ByteSymbol;
fn decode_def_index(&mut self) -> DefIndex;
}
/// This trait is used to allow decoder specific encodings of certain types.
/// It is similar to rustc_type_ir's TyDecoder.
pub trait SpanDecoder: BlobDecoder {
fn decode_span(&mut self) -> Span;
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 BlobDecoder for MemDecoder<'_> {
fn decode_symbol(&mut self) -> Symbol {
Symbol::intern(self.read_str())
}
fn decode_byte_symbol(&mut self) -> ByteSymbol {
ByteSymbol::intern(self.read_byte_str())
}
fn decode_def_index(&mut self) -> DefIndex {
panic!("cannot decode `DefIndex` with `MemDecoder`");
}
}
impl SpanDecoder for MemDecoder<'_> {
fn decode_span(&mut self) -> Span {
let lo = Decodable::decode(self);
@ -1318,14 +1335,6 @@ impl SpanDecoder for MemDecoder<'_> {
Span::new(lo, hi, SyntaxContext::root(), None)
}
fn decode_symbol(&mut self) -> Symbol {
Symbol::intern(self.read_str())
}
fn decode_byte_symbol(&mut self) -> ByteSymbol {
ByteSymbol::intern(self.read_byte_str())
}
fn decode_expn_id(&mut self) -> ExpnId {
panic!("cannot decode `ExpnId` with `MemDecoder`");
}
@ -1338,10 +1347,6 @@ impl SpanDecoder for MemDecoder<'_> {
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) }
}
@ -1357,13 +1362,13 @@ impl<D: SpanDecoder> Decodable<D> for Span {
}
}
impl<D: SpanDecoder> Decodable<D> for Symbol {
impl<D: BlobDecoder> Decodable<D> for Symbol {
fn decode(s: &mut D) -> Symbol {
s.decode_symbol()
}
}
impl<D: SpanDecoder> Decodable<D> for ByteSymbol {
impl<D: BlobDecoder> Decodable<D> for ByteSymbol {
fn decode(s: &mut D) -> ByteSymbol {
s.decode_byte_symbol()
}
@ -1387,7 +1392,7 @@ impl<D: SpanDecoder> Decodable<D> for CrateNum {
}
}
impl<D: SpanDecoder> Decodable<D> for DefIndex {
impl<D: BlobDecoder> Decodable<D> for DefIndex {
fn decode(s: &mut D) -> DefIndex {
s.decode_def_index()
}

View file

@ -52,7 +52,7 @@ use rustc_abi::{
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_error_messages::{DiagArgValue, IntoDiagArg, into_diag_arg_using_display};
use rustc_fs_util::try_canonicalize;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::{Symbol, kw, sym};
use serde_json::Value;
@ -830,7 +830,7 @@ impl LinkerFeatures {
}
crate::target_spec_enum! {
#[derive(Encodable, Decodable, HashStable_Generic)]
#[derive(Encodable, BlobDecodable, HashStable_Generic)]
pub enum PanicStrategy {
Unwind = "unwind",
Abort = "abort",
@ -840,7 +840,7 @@ crate::target_spec_enum! {
parse_error_type = "panic strategy";
}
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable, HashStable_Generic)]
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, BlobDecodable, HashStable_Generic)]
pub enum OnBrokenPipe {
Default,
Kill,