From f8bbf2ca0685b3d14795823bfff50ac2a0332d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jana=20D=C3=B6nszelmann?= Date: Thu, 27 Nov 2025 12:21:35 +0100 Subject: [PATCH] split out blob decode trait --- compiler/rustc_hir/src/definitions.rs | 8 +- compiler/rustc_hir/src/lang_items.rs | 4 +- compiler/rustc_hir/src/stability.rs | 10 +- compiler/rustc_hir/src/version.rs | 4 +- compiler/rustc_macros/src/lib.rs | 13 +- compiler/rustc_macros/src/serialize.rs | 17 +- compiler/rustc_metadata/src/locator.rs | 1 + compiler/rustc_metadata/src/rmeta/decoder.rs | 296 ++++++++++++------ .../src/rmeta/decoder/cstore_impl.rs | 11 +- .../src/rmeta/def_path_hash_map.rs | 7 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_metadata/src/rmeta/mod.rs | 11 +- compiler/rustc_metadata/src/rmeta/table.rs | 7 +- compiler/rustc_middle/src/middle/mod.rs | 4 +- .../rustc_middle/src/query/on_disk_cache.rs | 54 ++-- compiler/rustc_middle/src/ty/mod.rs | 6 +- compiler/rustc_session/src/config.rs | 6 +- compiler/rustc_session/src/cstore.rs | 6 +- compiler/rustc_session/src/options.rs | 8 +- compiler/rustc_span/src/def_id.rs | 4 +- compiler/rustc_span/src/edition.rs | 4 +- compiler/rustc_span/src/lib.rs | 45 +-- compiler/rustc_target/src/spec/mod.rs | 6 +- 23 files changed, 331 insertions(+), 203 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 07d5bcdd6ee9..01f84c90ec7a 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -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, @@ -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. diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 51e798d1e83b..4ac3e4e83e80 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -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.")] diff --git a/compiler/rustc_hir/src/stability.rs b/compiler/rustc_hir/src/stability.rs index 2b3a2a793163..9297f8e6cdcd 100644 --- a/compiler/rustc_hir/src/stability.rs +++ b/compiler/rustc_hir/src/stability.rs @@ -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, diff --git a/compiler/rustc_hir/src/version.rs b/compiler/rustc_hir/src/version.rs index bc2c38a49350..03182088d4c0 100644 --- a/compiler/rustc_hir/src/version.rs +++ b/compiler/rustc_hir/src/version.rs @@ -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, diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index a6f53d92e100..9f55143ecf53 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -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)] => diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index c7aaaf0da467..abf566288df4 100644 --- a/compiler/rustc_macros/src/serialize.rs +++ b/compiler/rustc_macros/src/serialize.rs @@ -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) diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 9fef22f9558d..6a441706a22b 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -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; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 25e7574d3b37..b1cac381e05b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -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, } -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>, 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(&mut self) -> LazyValue { + self.read_lazy_offset_then(|pos| LazyValue::from_position(pos)) + } + + fn read_lazy_array(&mut self, len: usize) -> LazyArray { + self.read_lazy_offset_then(|pos| LazyArray::from_position_and_num_elems(pos, len)) + } + + fn read_lazy_table(&mut self, width: usize, len: usize) -> LazyTable { + self.read_lazy_offset_then(|pos| LazyTable::from_position_and_encoded_size(pos, width, len)) + } + + #[inline] + fn read_lazy_offset_then(&mut self, f: impl Fn(NonZero) -> 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>, sess: Option<&'tcx Session>, tcx: Option>, - lazy_state: LazyState, - // Used for decoding interpret::AllocIds in a cached & thread-safe manner. alloc_decoding_session: Option>, } +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> { None @@ -180,23 +266,25 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { fn tcx(self) -> Option> { 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 LazyValue { #[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>, + T::Value<'tcx>: Decodable, { 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 { elem_counter: std::ops::Range, - dcx: DecodeContext<'a, 'tcx>, + dcx: D, _phantom: PhantomData T>, } -impl<'a, 'tcx, T: Decodable>> Iterator for DecodeIterator<'a, 'tcx, T> { +impl> Iterator for DecodeIterator { type Item = T; #[inline(always)] @@ -284,35 +388,30 @@ impl<'a, 'tcx, T: Decodable>> Iterator for DecodeIterato } } -impl<'a, 'tcx, T: Decodable>> ExactSizeIterator - for DecodeIterator<'a, 'tcx, T> -{ +impl> ExactSizeIterator for DecodeIterator { fn len(&self) -> usize { self.elem_counter.len() } } -unsafe impl<'a, 'tcx, T: Decodable>> TrustedLen - for DecodeIterator<'a, 'tcx, T> -{ -} +unsafe impl> TrustedLen for DecodeIterator {} impl LazyArray { #[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, M::Context> where - T::Value<'tcx>: Decodable>, + T::Value<'tcx>: Decodable, { 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(&mut self, f: impl Fn(NonZero) -> 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(&mut self) -> LazyValue { - self.read_lazy_offset_then(|pos| LazyValue::from_position(pos)) - } - - fn read_lazy_array(&mut self, len: usize) -> LazyArray { - self.read_lazy_offset_then(|pos| LazyArray::from_position_and_num_elems(pos, len)) - } - - fn read_lazy_table(&mut self, width: usize, len: usize) -> LazyTable { - 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> for ExpnIndex { +impl<'a, 'tcx> Decodable> 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> for SpanData { - fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SpanData { +impl<'a, 'tcx> Decodable> 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> for SpanData { } } -impl<'a, 'tcx> Decodable> for &'tcx [(ty::Clause<'tcx>, Span)] { - fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self { +impl<'a, 'tcx> Decodable> for &'tcx [(ty::Clause<'tcx>, Span)] { + fn decode(d: &mut MetadataDecodeContext<'a, 'tcx>) -> Self { ty::codec::RefDecodable::decode(d) } } -impl<'a, 'tcx, T> Decodable> for LazyValue { - fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self { +impl Decodable for LazyValue { + fn decode(decoder: &mut D) -> Self { decoder.read_lazy() } } -impl<'a, 'tcx, T> Decodable> for LazyArray { +impl Decodable for LazyArray { #[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> for LazyTable { - fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self { +impl Decodable for LazyTable { + 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> { - 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("".to_owned())); } return Err(None); @@ -731,7 +824,7 @@ impl MetadataBlob { fn root_pos(&self) -> NonZero { 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 diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 4831395f3164..24cfdc05e5cb 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -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 ProcessQueryValue<'_, Result, E>> for Option { } } -impl<'a, 'tcx, T: Copy + Decodable>> ProcessQueryValue<'tcx, &'tcx [T]> - for Option> +impl<'tcx, D: Decoder, T: Copy + Decodable> ProcessQueryValue<'tcx, &'tcx [T]> + for Option> { #[inline(always)] fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx [T] { @@ -74,8 +75,8 @@ impl<'a, 'tcx, T: Copy + Decodable>> ProcessQueryValue<' } } -impl<'a, 'tcx, T: Copy + Decodable>> - ProcessQueryValue<'tcx, Option<&'tcx [T]>> for Option> +impl<'tcx, D: Decoder, T: Copy + Decodable> ProcessQueryValue<'tcx, Option<&'tcx [T]>> + for Option> { #[inline(always)] fn process_decoded(self, tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> Option<&'tcx [T]> { diff --git a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs index a17b3e1047d0..949d7630f673 100644 --- a/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs +++ b/compiler/rustc_metadata/src/rmeta/def_path_hash_map.rs @@ -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), @@ -40,8 +41,8 @@ impl<'a, 'tcx> Encodable> for DefPathHashMapRef<'tcx> { } } -impl<'a, 'tcx> Decodable> for DefPathHashMapRef<'static> { - fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> { +impl<'a> Decodable> 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]); diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 4085fd5e70f1..94bba9445610 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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(); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index ac042c2ca75d..b1b9bcfcc506 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -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, impls: LazyArray, } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 4ce313f32a75..aaaed76bda9d 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -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, { /// 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(); diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 9091d492c26b..5739d132b66c 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -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 }, diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs index e8952d0492d1..c882d5d499bd 100644 --- a/compiler/rustc_middle/src/query/on_disk_cache.rs +++ b/compiler/rustc_middle/src/query/on_disk_cache.rs @@ -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> for &'tcx UnordSet { #[inline] fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d3e0fbb955c4..b4c20d7cadf9 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -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 { /// Visible everywhere (including in other crates). Public, diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f97a29e064b6..9b19961fcee4 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -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, diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 30f6256a75ef..8aef4b179f88 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -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, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 872a48efa366..d9792142a884 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -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),* } diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 77f01548bca2..484e626d4638 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -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 { diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index 28335734f4de..a27c5f62c1e5 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -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: diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 31f82860b73d..c6490b358ef8 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1296,20 +1296,37 @@ impl Encodable 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 Decodable for Span { } } -impl Decodable for Symbol { +impl Decodable for Symbol { fn decode(s: &mut D) -> Symbol { s.decode_symbol() } } -impl Decodable for ByteSymbol { +impl Decodable for ByteSymbol { fn decode(s: &mut D) -> ByteSymbol { s.decode_byte_symbol() } @@ -1387,7 +1392,7 @@ impl Decodable for CrateNum { } } -impl Decodable for DefIndex { +impl Decodable for DefIndex { fn decode(s: &mut D) -> DefIndex { s.decode_def_index() } diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 424026bdceab..c76e345bb7b6 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -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,