diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 07d5bcdd6ee92..01f84c90ec7ab 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 51e798d1e83b1..4ac3e4e83e80a 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 2b3a2a793163d..9297f8e6cdcd0 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 bc2c38a49350e..03182088d4c05 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 a6f53d92e1006..8cd6c02644481 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -72,14 +72,80 @@ decl_derive!( hash_stable::hash_stable_no_context_derive ); -decl_derive!([Decodable_NoContext] => serialize::decodable_nocontext_derive); +// Encoding and Decoding derives +decl_derive!([Decodable_NoContext] => + /// See docs on derive [`Decodable`]. + /// + /// Derives `Decodable for T where D: Decoder`. + serialize::decodable_nocontext_derive +); decl_derive!([Encodable_NoContext] => serialize::encodable_nocontext_derive); -decl_derive!([Decodable] => serialize::decodable_derive); +decl_derive!([Decodable] => + /// Derives `Decodable for T where D: SpanDecoder` + /// + /// # Deriving decoding traits + /// + /// > Some shared docs about decoding traits, since this is likely the first trait you find + /// + /// The difference between these derives can be subtle! + /// At a high level, there's the `T: Decodable` trait that says some type `T` + /// can be decoded using a decoder `D`. There are various decoders! + /// The different derives place different *trait* bounds on this type `D`. + /// + /// Even though this derive, based on its name, seems like the most vanilla one, + /// it actually places a pretty strict bound on `D`: `SpanDecoder`. + /// It means that types that derive this can contain spans, among other things, + /// and still be decoded. The reason this is hard is that at least in metadata, + /// spans can only be decoded later, once some information from the header + /// is already decoded to properly deal with spans. + /// + /// The hierarchy is roughly: + /// + /// - derive [`Decodable_NoContext`] is the most relaxed bounds that could be placed on `D`, + /// and is only really suited for structs and enums containing primitive types. + /// - derive [`BlobDecodable`] may be a better default, than deriving `Decodable`: + /// it places fewer requirements on `D`, while still allowing some complex types to be decoded. + /// - derive [`LazyDecodable`]: Only for types containing `Lazy{Array,Table,Value}`. + /// - derive [`Decodable`] for structures containing spans. Requires `D: SpanDecoder` + /// - derive [`TyDecodable`] for types that require access to the `TyCtxt` while decoding. + /// For example: arena allocated types. + serialize::decodable_derive +); decl_derive!([Encodable] => serialize::encodable_derive); -decl_derive!([TyDecodable] => serialize::type_decodable_derive); +decl_derive!([TyDecodable] => + /// See docs on derive [`Decodable`]. + /// + /// Derives `Decodable for T where D: TyDecoder`. + serialize::type_decodable_derive +); decl_derive!([TyEncodable] => serialize::type_encodable_derive); -decl_derive!([MetadataDecodable] => serialize::meta_decodable_derive); -decl_derive!([MetadataEncodable] => serialize::meta_encodable_derive); +decl_derive!([LazyDecodable] => + /// See docs on derive [`Decodable`]. + /// + /// Derives `Decodable for T where D: LazyDecoder`. + /// This constrains the decoder to be specifically the decoder that can decode + /// `LazyArray`s, `LazyValue`s amd `LazyTable`s in metadata. + /// Therefore, we only need this on things containing LazyArray really. + /// + /// Most decodable derives mirror an encodable derive. + /// [`LazyDecodable`] and [`BlobDecodable`] together roughly mirror [`MetadataEncodable`] + serialize::lazy_decodable_derive +); +decl_derive!([BlobDecodable] => + /// See docs on derive [`Decodable`]. + /// + /// Derives `Decodable for T where D: BlobDecoder`. + /// + /// Most decodable derives mirror an encodable derive. + /// [`LazyDecodable`] and [`BlobDecodable`] together roughly mirror [`MetadataEncodable`] + serialize::blob_decodable_derive +); +decl_derive!([MetadataEncodable] => + /// Most encodable derives mirror a decodable derive. + /// [`MetadataEncodable`] is roughly mirrored by the combination of [`LazyDecodable`] and [`BlobDecodable`] + serialize::meta_encodable_derive +); + decl_derive!( [TypeFoldable, attributes(type_foldable)] => /// Derives `TypeFoldable` for the annotated `struct` or `enum` (`union` is not supported). diff --git a/compiler/rustc_macros/src/serialize.rs b/compiler/rustc_macros/src/serialize.rs index c7aaaf0da4679..5ae6fb241c98d 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 meta_decodable_derive( +pub(super) fn blob_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: ::rustc_span::BlobDecoder }); + s.add_bounds(synstructure::AddBounds::Generics); + + decodable_body(s, decoder_ty) +} + +pub(super) fn lazy_decodable_derive( + mut s: synstructure::Structure<'_>, +) -> proc_macro2::TokenStream { + 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/creader.rs b/compiler/rustc_metadata/src/creader.rs index 95862ce01687d..e0aae4c4b3a07 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -276,8 +276,9 @@ impl CStore { .filter_map(|(cnum, data)| data.as_deref().map(|data| (cnum, data))) } - pub fn all_proc_macro_def_ids(&self) -> impl Iterator { - self.iter_crate_data().flat_map(|(krate, data)| data.proc_macros_for_crate(krate, self)) + pub fn all_proc_macro_def_ids(&self, tcx: TyCtxt<'_>) -> impl Iterator { + self.iter_crate_data() + .flat_map(move |(krate, data)| data.proc_macros_for_crate(tcx, krate, self)) } fn push_dependencies_in_postorder(&self, deps: &mut IndexSet, cnum: CrateNum) { @@ -683,6 +684,7 @@ impl CStore { }; let crate_metadata = CrateMetadata::new( + tcx, self, metadata, crate_root, @@ -778,7 +780,7 @@ impl CStore { self.used_extern_options.insert(name); match self.maybe_resolve_crate(tcx, name, dep_kind, origin) { Ok(cnum) => { - self.set_used_recursively(cnum); + self.set_used_recursively(tcx, cnum); Some(cnum) } Err(err) => { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 25e7574d3b376..bf7818b499331 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}; @@ -28,12 +29,12 @@ use rustc_middle::{bug, implement_ty_decoder}; use rustc_proc_macro::bridge::client::ProcMacro; use rustc_serialize::opaque::MemDecoder; use rustc_serialize::{Decodable, Decoder}; -use rustc_session::Session; 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,36 +155,116 @@ struct ImportedSourceFile { translated_source_file: Arc, } -pub(super) struct DecodeContext<'a, 'tcx> { +/// Decode context used when we just have a blob of metadata from which we have to decode a header +/// and [`CrateRoot`]. After that, [`MetadataDecodeContext`] can be used. +/// Most notably, [`BlobDecodeContext]` doesn't implement [`SpanDecoder`] +pub(super) struct BlobDecodeContext<'a> { opaque: MemDecoder<'a>, - cdata: Option>, blob: &'a MetadataBlob, - sess: Option<&'tcx Session>, - tcx: Option>, - lazy_state: LazyState, +} + +/// This trait abstracts over decoders that can decode lazy values using [`LazyState`]: +/// +/// - [`LazyValue`] +/// - [`LazyArray`] +/// - [`LazyTable`] +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. +/// Can be constructed from a [`TyCtxt`] and [`CrateMetadataRef`] (see the [`Metadata`] trait) +pub(super) struct MetadataDecodeContext<'a, 'tcx> { + blob_decoder: BlobDecodeContext<'a>, + cdata: CrateMetadataRef<'a>, + tcx: TyCtxt<'tcx>, // Used for decoding interpret::AllocIds in a cached & thread-safe manner. - alloc_decoding_session: Option>, + alloc_decoding_session: AllocDecodingSession<'a>, } -/// Abstract over the various ways one can create metadata decoders. -pub(super) trait Metadata<'a, 'tcx>: Copy { - fn blob(self) -> &'a MetadataBlob; +impl<'a, 'tcx> LazyDecoder for MetadataDecodeContext<'a, 'tcx> { + fn set_lazy_state(&mut self, state: LazyState) { + self.lazy_state = state; + } - fn cdata(self) -> Option> { - None + fn get_lazy_state(&self) -> LazyState { + self.lazy_state } - fn sess(self) -> Option<&'tcx Session> { - None +} + +impl<'a, 'tcx> DerefMut for MetadataDecodeContext<'a, 'tcx> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.blob_decoder } - fn tcx(self) -> Option> { - None +} + +impl<'a, 'tcx> Deref for MetadataDecodeContext<'a, 'tcx> { + type Target = BlobDecodeContext<'a>; + + fn deref(&self) -> &Self::Target { + &self.blob_decoder } +} - fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> { - let tcx = self.tcx(); - DecodeContext { +pub(super) trait Metadata<'a>: Copy { + type Context: BlobDecoder + LazyDecoder; + + fn blob(self) -> &'a MetadataBlob; + fn decoder(self, pos: usize) -> Self::Context; +} + +impl<'a> Metadata<'a> 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 @@ -191,86 +272,49 @@ pub(super) trait Metadata<'a, 'tcx>: Copy { // 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(), - cdata: self.cdata(), - blob: self.blob(), - sess: self.sess().or(tcx.map(|tcx| tcx.sess)), - tcx, + opaque: MemDecoder::new(self, pos).unwrap(), lazy_state: LazyState::NoNode, - alloc_decoding_session: self - .cdata() - .map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()), + blob: self.blob(), } } } -impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob { - #[inline] - fn blob(self) -> &'a MetadataBlob { - self - } -} - -impl<'a, 'tcx> Metadata<'a, 'tcx> for CrateMetadataRef<'a> { - #[inline] - fn blob(self) -> &'a MetadataBlob { - &self.cdata.blob - } - #[inline] - fn cdata(self) -> Option> { - Some(self) - } -} +impl<'a, 'tcx> Metadata<'a> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) { + type Context = MetadataDecodeContext<'a, 'tcx>; -impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, &'tcx Session) { - #[inline] fn blob(self) -> &'a MetadataBlob { &self.0.cdata.blob } - #[inline] - fn cdata(self) -> Option> { - Some(self.0) - } - #[inline] - fn sess(self) -> Option<&'tcx Session> { - Some(self.1) - } -} -impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) { - #[inline] - fn blob(self) -> &'a MetadataBlob { - &self.0.cdata.blob - } - #[inline] - fn cdata(self) -> Option> { - Some(self.0) - } - #[inline] - fn tcx(self) -> Option> { - Some(self.1) + fn decoder(self, pos: usize) -> MetadataDecodeContext<'a, 'tcx> { + MetadataDecodeContext { + blob_decoder: self.blob().decoder(pos), + cdata: self.0, + tcx: self.1, + alloc_decoding_session: self.0.cdata.alloc_decoding_state.new_decoding_session(), + } } } impl LazyValue { #[inline] - fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx> + fn decode<'a, 'tcx, M: Metadata<'a>>(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,96 +328,42 @@ 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: Metadata<'a>>( 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 { - bug!( - "No TyCtxt found for decoding. \ - You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." - ); - }; - tcx + fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { + self.cdata.map_encoded_cnum_to_current(cnum) } +} +impl<'a> BlobDecodeContext<'a> { #[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"); - self.cdata.unwrap() - } - - #[inline] - fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum { - self.cdata().map_encoded_cnum_to_current(cnum) - } - - #[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)) - } - - #[inline] - fn read_raw_bytes(&mut self, len: usize) -> &[u8] { - self.opaque.read_raw_bytes(len) - } - fn decode_symbol_or_byte_symbol( &mut self, new_from_index: impl Fn(u32) -> S, @@ -397,21 +387,21 @@ 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] fn interner(&self) -> TyCtxt<'tcx> { - self.tcx() + self.tcx } fn cached_ty_for_shorthand(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx> where F: FnOnce(&mut Self) -> Ty<'tcx>, { - let tcx = self.tcx(); + let tcx = self.tcx; - let key = ty::CReaderCacheKey { cnum: Some(self.cdata().cnum), pos: shorthand }; + let key = ty::CReaderCacheKey { cnum: Some(self.cdata.cnum), pos: shorthand }; if let Some(&ty) = tcx.ty_rcache.borrow().get(&key) { return ty; @@ -426,35 +416,31 @@ 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 } fn decode_alloc_id(&mut self) -> rustc_middle::mir::interpret::AllocId { - if let Some(alloc_decoding_session) = self.alloc_decoding_session { - alloc_decoding_session.decode_alloc_id(self) - } else { - bug!("Attempting to decode interpret::AllocId without CrateMetadata") - } + let ads = self.alloc_decoding_session; + ads.decode_alloc_id(self) } } -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() + self.tcx.sess.psess.attr_id_generator.mk_attr_id() } fn decode_crate_num(&mut self) -> CrateNum { @@ -462,23 +448,13 @@ 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) } } fn decode_syntax_context(&mut self) -> SyntaxContext { - let cdata = self.cdata(); - - let Some(sess) = self.sess else { - bug!( - "Cannot decode SyntaxContext without Session.\ - You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." - ); - }; + let cdata = self.cdata; + let tcx = self.tcx; let cname = cdata.root.name(); rustc_span::hygiene::decode_syntax_context(self, &cdata.hygiene_context, |_, id| { @@ -486,22 +462,16 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> { cdata .root .syntax_contexts - .get(cdata, id) + .get((cdata, tcx), id) .unwrap_or_else(|| panic!("Missing SyntaxContext {id:?} for crate {cname:?}")) - .decode((cdata, sess)) + .decode((cdata, tcx)) }) } fn decode_expn_id(&mut self) -> ExpnId { - let local_cdata = self.cdata(); - - let Some(sess) = self.sess else { - bug!( - "Cannot decode ExpnId without Session. \ - You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." - ); - }; + let local_cdata = self.cdata; + let tcx = self.tcx; let cnum = CrateNum::decode(self); let index = u32::decode(self); @@ -518,15 +488,15 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> { let expn_data = crate_data .root .expn_data - .get(crate_data, index) + .get((crate_data, tcx), index) .unwrap() - .decode((crate_data, sess)); + .decode((crate_data, tcx)); let expn_hash = crate_data .root .expn_hashes - .get(crate_data, index) + .get((crate_data, tcx), index) .unwrap() - .decode((crate_data, sess)); + .decode((crate_data, tcx)); (expn_data, expn_hash) }); expn_id @@ -554,7 +524,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 +560,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)); @@ -587,12 +575,7 @@ impl<'a, 'tcx> Decodable> for SpanData { let len = tag.length().unwrap_or_else(|| BytePos::decode(decoder)); let hi = lo + len; - let Some(sess) = decoder.sess else { - bug!( - "Cannot decode Span without Session. \ - You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`." - ) - }; + let tcx = decoder.tcx; // Index of the file in the corresponding crate's list of encoded files. let metadata_index = u32::decode(decoder); @@ -626,18 +609,17 @@ impl<'a, 'tcx> Decodable> for SpanData { // we can call `imported_source_file` for the proper crate, and binary search // through the returned slice using our span. let source_file = if tag.kind() == SpanKind::Local { - decoder.cdata().imported_source_file(metadata_index, sess) + decoder.cdata.imported_source_file(tcx, metadata_index) } else { // When we encode a proc-macro crate, all `Span`s should be encoded // with `TAG_VALID_SPAN_LOCAL` - if decoder.cdata().root.is_proc_macro_crate() { + if decoder.cdata.root.is_proc_macro_crate() { // Decode `CrateNum` as u32 - using `CrateNum::decode` will ICE // since we don't have `cnum_map` populated. let cnum = u32::decode(decoder); panic!( "Decoding of crate {:?} tried to access proc-macro dep {:?}", - decoder.cdata().root.header.name, - cnum + decoder.cdata.root.header.name, cnum ); } // tag is TAG_VALID_SPAN_FOREIGN, checked by `debug_assert` above @@ -647,8 +629,8 @@ impl<'a, 'tcx> Decodable> for SpanData { cnum ); - let foreign_data = decoder.cdata().cstore.get_crate_data(cnum); - foreign_data.imported_source_file(metadata_index, sess) + let foreign_data = decoder.cdata.cstore.get_crate_data(cnum); + foreign_data.imported_source_file(tcx, metadata_index) }; // Make sure our span is well-formed. @@ -677,43 +659,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 +720,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() } @@ -978,7 +967,7 @@ impl<'a> CrateMetadataRef<'a> { bug!("missing `{descr}` for {:?}", self.local_def_id(id)) } - fn raw_proc_macro(self, id: DefIndex) -> &'a ProcMacro { + fn raw_proc_macro(self, tcx: TyCtxt<'_>, id: DefIndex) -> &'a ProcMacro { // DefIndex's in root.proc_macro_data have a one-to-one correspondence // with items in 'raw_proc_macros'. let pos = self @@ -987,7 +976,7 @@ impl<'a> CrateMetadataRef<'a> { .as_ref() .unwrap() .macros - .decode(self) + .decode((self, tcx)) .position(|i| i == id) .unwrap(); &self.raw_proc_macros.unwrap()[pos] @@ -1009,20 +998,20 @@ impl<'a> CrateMetadataRef<'a> { self.opt_item_name(item_index).expect("no encoded ident for item") } - fn opt_item_ident(self, item_index: DefIndex, sess: &Session) -> Option { + fn opt_item_ident(self, tcx: TyCtxt<'_>, item_index: DefIndex) -> Option { let name = self.opt_item_name(item_index)?; let span = self .root .tables .def_ident_span - .get(self, item_index) + .get((self, tcx), item_index) .unwrap_or_else(|| self.missing("def_ident_span", item_index)) - .decode((self, sess)); + .decode((self, tcx)); Some(Ident::new(name, span)) } - fn item_ident(self, item_index: DefIndex, sess: &Session) -> Ident { - self.opt_item_ident(item_index, sess).expect("no encoded ident for item") + fn item_ident(self, tcx: TyCtxt<'_>, item_index: DefIndex) -> Ident { + self.opt_item_ident(tcx, item_index).expect("no encoded ident for item") } #[inline] @@ -1030,25 +1019,25 @@ impl<'a> CrateMetadataRef<'a> { if cnum == LOCAL_CRATE { self.cnum } else { self.cnum_map[cnum] } } - fn def_kind(self, item_id: DefIndex) -> DefKind { + fn def_kind(self, tcx: TyCtxt<'_>, item_id: DefIndex) -> DefKind { self.root .tables .def_kind - .get(self, item_id) + .get((self, tcx), item_id) .unwrap_or_else(|| self.missing("def_kind", item_id)) } - fn get_span(self, index: DefIndex, sess: &Session) -> Span { + fn get_span(self, tcx: TyCtxt<'_>, index: DefIndex) -> Span { self.root .tables .def_span - .get(self, index) + .get((self, tcx), index) .unwrap_or_else(|| self.missing("def_span", index)) - .decode((self, sess)) + .decode((self, tcx)) } - fn load_proc_macro<'tcx>(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtension { - let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) { + fn load_proc_macro<'tcx>(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> SyntaxExtension { + let (name, kind, helper_attrs) = match *self.raw_proc_macro(tcx, id) { ProcMacro::CustomDerive { trait_name, attributes, client } => { let helper_attrs = attributes.iter().cloned().map(Symbol::intern).collect::>(); @@ -1067,11 +1056,11 @@ impl<'a> CrateMetadataRef<'a> { }; let sess = tcx.sess; - let attrs: Vec<_> = self.get_item_attrs(id, sess).collect(); + let attrs: Vec<_> = self.get_item_attrs(tcx, id).collect(); SyntaxExtension::new( sess, kind, - self.get_span(id, sess), + self.get_span(tcx, id), helper_attrs, self.root.edition, Symbol::intern(name), @@ -1082,6 +1071,7 @@ impl<'a> CrateMetadataRef<'a> { fn get_variant( self, + tcx: TyCtxt<'_>, kind: DefKind, index: DefIndex, parent_did: DefId, @@ -1093,7 +1083,8 @@ impl<'a> CrateMetadataRef<'a> { _ => bug!(), }; - let data = self.root.tables.variant_data.get(self, index).unwrap().decode(self); + let data = + self.root.tables.variant_data.get((self, tcx), index).unwrap().decode((self, tcx)); let variant_did = if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None }; @@ -1106,13 +1097,13 @@ impl<'a> CrateMetadataRef<'a> { variant_did, ctor, data.discr, - self.get_associated_item_or_field_def_ids(index) + self.get_associated_item_or_field_def_ids(tcx, index) .map(|did| ty::FieldDef { did, name: self.item_name(did.index), - vis: self.get_visibility(did.index), - safety: self.get_safety(did.index), - value: self.get_default_field(did.index), + vis: self.get_visibility(tcx, did.index), + safety: self.get_safety(tcx, did.index), + value: self.get_default_field(tcx, did.index), }) .collect(), parent_did, @@ -1122,8 +1113,8 @@ impl<'a> CrateMetadataRef<'a> { ) } - fn get_adt_def<'tcx>(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'tcx> { - let kind = self.def_kind(item_id); + fn get_adt_def<'tcx>(self, tcx: TyCtxt<'tcx>, item_id: DefIndex) -> ty::AdtDef<'tcx> { + let kind = self.def_kind(tcx, item_id); let did = self.local_def_id(item_id); let adt_kind = match kind { @@ -1132,25 +1123,26 @@ impl<'a> CrateMetadataRef<'a> { DefKind::Union => ty::AdtKind::Union, _ => bug!("get_adt_def called on a non-ADT {:?}", did), }; - let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self); + let repr = + self.root.tables.repr_options.get((self, tcx), item_id).unwrap().decode((self, tcx)); let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind { self.root .tables .module_children_non_reexports - .get(self, item_id) + .get((self, tcx), item_id) .expect("variants are not encoded for an enum") - .decode(self) + .decode((self, tcx)) .filter_map(|index| { - let kind = self.def_kind(index); + let kind = self.def_kind(tcx, index); match kind { DefKind::Ctor(..) => None, - _ => Some(self.get_variant(kind, index, did)), + _ => Some(self.get_variant(tcx, kind, index, did)), } }) .collect() } else { - std::iter::once(self.get_variant(kind, item_id, did)).collect() + std::iter::once(self.get_variant(tcx, kind, item_id, did)).collect() }; variants.sort_by_key(|(idx, _)| *idx); @@ -1163,44 +1155,44 @@ impl<'a> CrateMetadataRef<'a> { ) } - fn get_visibility(self, id: DefIndex) -> Visibility { + fn get_visibility(self, tcx: TyCtxt<'_>, id: DefIndex) -> Visibility { self.root .tables .visibility - .get(self, id) + .get((self, tcx), id) .unwrap_or_else(|| self.missing("visibility", id)) - .decode(self) + .decode((self, tcx)) .map_id(|index| self.local_def_id(index)) } - fn get_safety(self, id: DefIndex) -> Safety { - self.root.tables.safety.get(self, id) + fn get_safety(self, tcx: TyCtxt<'_>, id: DefIndex) -> Safety { + self.root.tables.safety.get((self, tcx), id) } - fn get_default_field(self, id: DefIndex) -> Option { - self.root.tables.default_fields.get(self, id).map(|d| d.decode(self)) + fn get_default_field(self, tcx: TyCtxt<'_>, id: DefIndex) -> Option { + self.root.tables.default_fields.get((self, tcx), id).map(|d| d.decode((self, tcx))) } - fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId { + fn get_expn_that_defined(self, tcx: TyCtxt<'_>, id: DefIndex) -> ExpnId { self.root .tables .expn_that_defined - .get(self, id) + .get((self, tcx), id) .unwrap_or_else(|| self.missing("expn_that_defined", id)) - .decode((self, sess)) + .decode((self, tcx)) } - fn get_debugger_visualizers(self) -> Vec { - self.root.debugger_visualizers.decode(self).collect::>() + fn get_debugger_visualizers(self, tcx: TyCtxt<'_>) -> Vec { + self.root.debugger_visualizers.decode((self, tcx)).collect::>() } /// Iterates over all the stability attributes in the given crate. - fn get_lib_features(self) -> LibFeatures { + fn get_lib_features(self, tcx: TyCtxt<'_>) -> LibFeatures { LibFeatures { stability: self .root .lib_features - .decode(self) + .decode((self, tcx)) .map(|(sym, stab)| (sym, (stab, DUMMY_SP))) .collect(), } @@ -1210,7 +1202,7 @@ impl<'a> CrateMetadataRef<'a> { /// has an `implied_by` meta item, then the mapping from the implied feature to the actual /// feature is a stability implication). fn get_stability_implications<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Symbol)] { - tcx.arena.alloc_from_iter(self.root.stability_implications.decode(self)) + tcx.arena.alloc_from_iter(self.root.stability_implications.decode((self, tcx))) } /// Iterates over the lang items in the given crate. @@ -1218,15 +1210,15 @@ impl<'a> CrateMetadataRef<'a> { tcx.arena.alloc_from_iter( self.root .lang_items - .decode(self) + .decode((self, tcx)) .map(move |(def_index, index)| (self.local_def_id(def_index), index)), ) } fn get_stripped_cfg_items<'tcx>( self, - cnum: CrateNum, tcx: TyCtxt<'tcx>, + cnum: CrateNum, ) -> &'tcx [StrippedCfgItem] { let item_names = self .root @@ -1237,12 +1229,12 @@ impl<'a> CrateMetadataRef<'a> { } /// Iterates over the diagnostic items in the given crate. - fn get_diagnostic_items(self) -> DiagnosticItems { + fn get_diagnostic_items(self, tcx: TyCtxt<'_>) -> DiagnosticItems { let mut id_to_name = DefIdMap::default(); let name_to_id = self .root .diagnostic_items - .decode(self) + .decode((self, tcx)) .map(|(name, def_index)| { let id = self.local_def_id(def_index); id_to_name.insert(id, name); @@ -1252,10 +1244,10 @@ impl<'a> CrateMetadataRef<'a> { DiagnosticItems { id_to_name, name_to_id } } - fn get_mod_child(self, id: DefIndex, sess: &Session) -> ModChild { - let ident = self.item_ident(id, sess); - let res = Res::Def(self.def_kind(id), self.local_def_id(id)); - let vis = self.get_visibility(id); + fn get_mod_child(self, tcx: TyCtxt<'_>, id: DefIndex) -> ModChild { + let ident = self.item_ident(tcx, id); + let res = Res::Def(self.def_kind(tcx, id), self.local_def_id(id)); + let vis = self.get_visibility(tcx, id); ModChild { ident, res, vis, reexport_chain: Default::default() } } @@ -1264,30 +1256,27 @@ impl<'a> CrateMetadataRef<'a> { /// including both proper items and reexports. /// Module here is understood in name resolution sense - it can be a `mod` item, /// or a crate root, or an enum, or a trait. - fn get_module_children( - self, - id: DefIndex, - sess: &'a Session, - ) -> impl Iterator { + fn get_module_children(self, tcx: TyCtxt<'_>, id: DefIndex) -> impl Iterator { gen move { if let Some(data) = &self.root.proc_macro_data { // If we are loading as a proc macro, we want to return // the view of this crate as a proc macro crate. if id == CRATE_DEF_INDEX { - for child_index in data.macros.decode(self) { - yield self.get_mod_child(child_index, sess); + for child_index in data.macros.decode((self, tcx)) { + yield self.get_mod_child(tcx, child_index); } } } else { // Iterate over all children. - let non_reexports = self.root.tables.module_children_non_reexports.get(self, id); - for child_index in non_reexports.unwrap().decode(self) { - yield self.get_mod_child(child_index, sess); + let non_reexports = + self.root.tables.module_children_non_reexports.get((self, tcx), id); + for child_index in non_reexports.unwrap().decode((self, tcx)) { + yield self.get_mod_child(tcx, child_index); } - let reexports = self.root.tables.module_children_reexports.get(self, id); + let reexports = self.root.tables.module_children_reexports.get((self, tcx), id); if !reexports.is_default() { - for reexport in reexports.decode((self, sess)) { + for reexport in reexports.decode((self, tcx)) { yield reexport; } } @@ -1295,46 +1284,51 @@ impl<'a> CrateMetadataRef<'a> { } } - fn is_ctfe_mir_available(self, id: DefIndex) -> bool { - self.root.tables.mir_for_ctfe.get(self, id).is_some() + fn is_ctfe_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { + self.root.tables.mir_for_ctfe.get((self, tcx), id).is_some() } - fn is_item_mir_available(self, id: DefIndex) -> bool { - self.root.tables.optimized_mir.get(self, id).is_some() + fn is_item_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { + self.root.tables.optimized_mir.get((self, tcx), id).is_some() } - fn get_fn_has_self_parameter(self, id: DefIndex, sess: &'a Session) -> bool { + fn get_fn_has_self_parameter(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool { self.root .tables .fn_arg_idents - .get(self, id) + .get((self, tcx), id) .expect("argument names not encoded for a function") - .decode((self, sess)) + .decode((self, tcx)) .nth(0) .is_some_and(|ident| matches!(ident, Some(Ident { name: kw::SelfLower, .. }))) } - fn get_associated_item_or_field_def_ids(self, id: DefIndex) -> impl Iterator { + fn get_associated_item_or_field_def_ids( + self, + tcx: TyCtxt<'_>, + id: DefIndex, + ) -> impl Iterator { self.root .tables .associated_item_or_field_def_ids - .get(self, id) + .get((self, tcx), id) .unwrap_or_else(|| self.missing("associated_item_or_field_def_ids", id)) - .decode(self) + .decode((self, tcx)) .map(move |child_index| self.local_def_id(child_index)) } - fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem { - let kind = match self.def_kind(id) { + fn get_associated_item(self, tcx: TyCtxt<'_>, id: DefIndex) -> ty::AssocItem { + let kind = match self.def_kind(tcx, id) { DefKind::AssocConst => ty::AssocKind::Const { name: self.item_name(id) }, DefKind::AssocFn => ty::AssocKind::Fn { name: self.item_name(id), - has_self: self.get_fn_has_self_parameter(id, sess), + has_self: self.get_fn_has_self_parameter(tcx, id), }, DefKind::AssocTy => { - let data = if let Some(rpitit_info) = self.root.tables.opt_rpitit_info.get(self, id) + let data = if let Some(rpitit_info) = + self.root.tables.opt_rpitit_info.get((self, tcx), id) { - ty::AssocTypeData::Rpitit(rpitit_info.decode(self)) + ty::AssocTypeData::Rpitit(rpitit_info.decode((self, tcx))) } else { ty::AssocTypeData::Normal(self.item_name(id)) }; @@ -1342,30 +1336,33 @@ impl<'a> CrateMetadataRef<'a> { } _ => bug!("cannot get associated-item of `{:?}`", self.def_key(id)), }; - let container = self.root.tables.assoc_container.get(self, id).unwrap().decode(self); + let container = + self.root.tables.assoc_container.get((self, tcx), id).unwrap().decode((self, tcx)); ty::AssocItem { kind, def_id: self.local_def_id(id), container } } - fn get_ctor(self, node_id: DefIndex) -> Option<(CtorKind, DefId)> { - match self.def_kind(node_id) { + fn get_ctor(self, tcx: TyCtxt<'_>, node_id: DefIndex) -> Option<(CtorKind, DefId)> { + match self.def_kind(tcx, node_id) { DefKind::Struct | DefKind::Variant => { - let vdata = self.root.tables.variant_data.get(self, node_id).unwrap().decode(self); + let vdata = self + .root + .tables + .variant_data + .get((self, tcx), node_id) + .unwrap() + .decode((self, tcx)); vdata.ctor.map(|(kind, index)| (kind, self.local_def_id(index))) } _ => None, } } - fn get_item_attrs( - self, - id: DefIndex, - sess: &'a Session, - ) -> impl Iterator { + fn get_item_attrs(self, tcx: TyCtxt<'_>, id: DefIndex) -> impl Iterator { self.root .tables .attributes - .get(self, id) + .get((self, tcx), id) .unwrap_or_else(|| { // Structure and variant constructors don't have any attributes encoded for them, // but we assume that someone passing a constructor ID actually wants to look at @@ -1376,10 +1373,10 @@ impl<'a> CrateMetadataRef<'a> { self.root .tables .attributes - .get(self, parent_id) + .get((self, tcx), parent_id) .expect("no encoded attributes for a structure or variant") }) - .decode((self, sess)) + .decode((self, tcx)) } fn get_inherent_implementations_for_type<'tcx>( @@ -1391,27 +1388,27 @@ impl<'a> CrateMetadataRef<'a> { self.root .tables .inherent_impls - .get(self, id) - .decode(self) + .get((self, tcx), id) + .decode((self, tcx)) .map(|index| self.local_def_id(index)), ) } /// Decodes all traits in the crate (for rustdoc and rustc diagnostics). - fn get_traits(self) -> impl Iterator { - self.root.traits.decode(self).map(move |index| self.local_def_id(index)) + fn get_traits(self, tcx: TyCtxt<'_>) -> impl Iterator { + self.root.traits.decode((self, tcx)).map(move |index| self.local_def_id(index)) } /// Decodes all trait impls in the crate (for rustdoc). - fn get_trait_impls(self) -> impl Iterator { + fn get_trait_impls(self, tcx: TyCtxt<'_>) -> impl Iterator { self.cdata.trait_impls.values().flat_map(move |impls| { - impls.decode(self).map(move |(impl_index, _)| self.local_def_id(impl_index)) + impls.decode((self, tcx)).map(move |(impl_index, _)| self.local_def_id(impl_index)) }) } fn get_incoherent_impls<'tcx>(self, tcx: TyCtxt<'tcx>, simp: SimplifiedType) -> &'tcx [DefId] { if let Some(impls) = self.cdata.incoherent_impls.get(&simp) { - tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx))) + tcx.arena.alloc_from_iter(impls.decode((self, tcx)).map(|idx| self.local_def_id(idx))) } else { &[] } @@ -1436,7 +1433,7 @@ impl<'a> CrateMetadataRef<'a> { if let Some(impls) = self.trait_impls.get(&key) { tcx.arena.alloc_from_iter( impls - .decode(self) + .decode((self, tcx)) .map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty)), ) } else { @@ -1444,21 +1441,21 @@ impl<'a> CrateMetadataRef<'a> { } } - fn get_native_libraries(self, sess: &'a Session) -> impl Iterator { - self.root.native_libraries.decode((self, sess)) + fn get_native_libraries(self, tcx: TyCtxt<'_>) -> impl Iterator { + self.root.native_libraries.decode((self, tcx)) } - fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span { + fn get_proc_macro_quoted_span(self, tcx: TyCtxt<'_>, index: usize) -> Span { self.root .tables .proc_macro_quoted_spans - .get(self, index) + .get((self, tcx), index) .unwrap_or_else(|| panic!("Missing proc macro quoted span: {index:?}")) - .decode((self, sess)) + .decode((self, tcx)) } - fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator { - self.root.foreign_modules.decode((self, sess)) + fn get_foreign_modules(self, tcx: TyCtxt<'_>) -> impl Iterator { + self.root.foreign_modules.decode((self, tcx)) } fn get_dylib_dependency_formats<'tcx>( @@ -1466,25 +1463,30 @@ impl<'a> CrateMetadataRef<'a> { tcx: TyCtxt<'tcx>, ) -> &'tcx [(CrateNum, LinkagePreference)] { tcx.arena.alloc_from_iter( - self.root.dylib_dependency_formats.decode(self).enumerate().flat_map(|(i, link)| { - let cnum = CrateNum::new(i + 1); // We skipped LOCAL_CRATE when encoding - link.map(|link| (self.cnum_map[cnum], link)) - }), + self.root.dylib_dependency_formats.decode((self, tcx)).enumerate().flat_map( + |(i, link)| { + let cnum = CrateNum::new(i + 1); // We skipped LOCAL_CRATE when encoding + link.map(|link| (self.cnum_map[cnum], link)) + }, + ), ) } fn get_missing_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] { - tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self)) + tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode((self, tcx))) } - fn get_exportable_items(self) -> impl Iterator { - self.root.exportable_items.decode(self).map(move |index| self.local_def_id(index)) + fn get_exportable_items(self, tcx: TyCtxt<'_>) -> impl Iterator { + self.root.exportable_items.decode((self, tcx)).map(move |index| self.local_def_id(index)) } - fn get_stable_order_of_exportable_impls(self) -> impl Iterator { + fn get_stable_order_of_exportable_impls( + self, + tcx: TyCtxt<'_>, + ) -> impl Iterator { self.root .stable_order_of_exportable_impls - .decode(self) + .decode((self, tcx)) .map(move |v| (self.local_def_id(v.0), v.1)) } @@ -1502,12 +1504,17 @@ impl<'a> CrateMetadataRef<'a> { tcx.arena.alloc_from_iter(self.root.exported_generic_symbols.decode((self, tcx))) } - fn get_macro(self, id: DefIndex, sess: &Session) -> ast::MacroDef { - match self.def_kind(id) { + fn get_macro(self, tcx: TyCtxt<'_>, id: DefIndex) -> ast::MacroDef { + match self.def_kind(tcx, id) { DefKind::Macro(_) => { - let macro_rules = self.root.tables.is_macro_rules.get(self, id); - let body = - self.root.tables.macro_definition.get(self, id).unwrap().decode((self, sess)); + let macro_rules = self.root.tables.is_macro_rules.get((self, tcx), id); + let body = self + .root + .tables + .macro_definition + .get((self, tcx), id) + .unwrap() + .decode((self, tcx)); ast::MacroDef { macro_rules, body: Box::new(body) } } _ => bug!(), @@ -1516,11 +1523,9 @@ impl<'a> CrateMetadataRef<'a> { #[inline] fn def_key(self, index: DefIndex) -> DefKey { - *self - .def_key_cache - .lock() - .entry(index) - .or_insert_with(|| self.root.tables.def_keys.get(self, index).unwrap().decode(self)) + *self.def_key_cache.lock().entry(index).or_insert_with(|| { + self.root.tables.def_keys.get(&self.blob, index).unwrap().decode(&self.blob) + }) } // Returns the path leading to the thing with this `id`. @@ -1536,7 +1541,7 @@ impl<'a> CrateMetadataRef<'a> { // relax the Default restriction will likely fix this. let fingerprint = Fingerprint::new( self.root.stable_crate_id.as_u64(), - self.root.tables.def_path_hashes.get(self, index), + self.root.tables.def_path_hashes.get(&self.blob, index), ); DefPathHash::new(self.root.stable_crate_id, fingerprint.split().1) } @@ -1546,9 +1551,13 @@ impl<'a> CrateMetadataRef<'a> { self.def_path_hash_map.def_path_hash_to_def_index(&hash) } - fn expn_hash_to_expn_id(self, sess: &Session, index_guess: u32, hash: ExpnHash) -> ExpnId { + fn expn_hash_to_expn_id(self, tcx: TyCtxt<'_>, index_guess: u32, hash: ExpnHash) -> ExpnId { let index_guess = ExpnIndex::from_u32(index_guess); - let old_hash = self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode(self)); + let old_hash = self + .root + .expn_hashes + .get((self, tcx), index_guess) + .map(|lazy| lazy.decode((self, tcx))); let index = if old_hash == Some(hash) { // Fast path: the expn and its index is unchanged from the @@ -1565,8 +1574,8 @@ impl<'a> CrateMetadataRef<'a> { UnhashMap::with_capacity_and_hasher(end_id as usize, Default::default()); for i in 0..end_id { let i = ExpnIndex::from_u32(i); - if let Some(hash) = self.root.expn_hashes.get(self, i) { - map.insert(hash.decode(self), i); + if let Some(hash) = self.root.expn_hashes.get((self, tcx), i) { + map.insert(hash.decode((self, tcx)), i); } } map @@ -1574,7 +1583,7 @@ impl<'a> CrateMetadataRef<'a> { map[&hash] }; - let data = self.root.expn_data.get(self, index).unwrap().decode((self, sess)); + let data = self.root.expn_data.get((self, tcx), index).unwrap().decode((self, tcx)); rustc_span::hygiene::register_expn_id(self.cnum, index, data, hash) } @@ -1603,9 +1612,9 @@ impl<'a> CrateMetadataRef<'a> { /// /// Proc macro crates don't currently export spans, so this function does not have /// to work for them. - fn imported_source_file(self, source_file_index: u32, sess: &Session) -> ImportedSourceFile { + fn imported_source_file(self, tcx: TyCtxt<'_>, source_file_index: u32) -> ImportedSourceFile { fn filter<'a>( - sess: &Session, + tcx: TyCtxt<'_>, real_source_base_dir: &Option, path: Option<&'a Path>, ) -> Option<&'a Path> { @@ -1613,13 +1622,13 @@ impl<'a> CrateMetadataRef<'a> { // Only spend time on further checks if we have what to translate *to*. real_source_base_dir.is_some() // Some tests need the translation to be always skipped. - && sess.opts.unstable_opts.translate_remapped_path_to_local_path + && tcx.sess.opts.unstable_opts.translate_remapped_path_to_local_path }) .filter(|virtual_dir| { // Don't translate away `/rustc/$hash` if we're still remapping to it, // since that means we're still building `std`/`rustc` that need it, // and we don't want the real path to leak into codegen/debuginfo. - !sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir) + !tcx.sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir) }) } @@ -1628,11 +1637,11 @@ impl<'a> CrateMetadataRef<'a> { real_source_base_dir: &Option, name: &mut rustc_span::FileName| { let virtual_source_base_dir = [ - filter(sess, real_source_base_dir, virtual_source_base_dir.map(Path::new)), + filter(tcx, real_source_base_dir, virtual_source_base_dir.map(Path::new)), filter( - sess, + tcx, real_source_base_dir, - sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref(), + tcx.sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref(), ), ]; @@ -1663,7 +1672,7 @@ impl<'a> CrateMetadataRef<'a> { // https://rust-lang.github.io/rfcs/3127-trim-paths.html#handling-sysroot-paths. // Other imported paths are not currently remapped (see #66251). let (user_remapped, applied) = - sess.source_map().path_mapping().map_prefix(&new_path); + tcx.sess.source_map().path_mapping().map_prefix(&new_path); let new_name = if applied { rustc_span::RealFileName::Remapped { local_path: Some(new_path.clone()), @@ -1682,7 +1691,8 @@ impl<'a> CrateMetadataRef<'a> { real_source_base_dir: &Option, subdir: &str, name: &mut rustc_span::FileName| { - if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base + if let Some(virtual_dir) = + &tcx.sess.opts.unstable_opts.simulate_remapped_rust_src_base && let Some(real_dir) = real_source_base_dir && let rustc_span::FileName::Real(old_name) = name { @@ -1719,9 +1729,9 @@ impl<'a> CrateMetadataRef<'a> { let source_file_to_import = self .root .source_map - .get(self, source_file_index) + .get((self, tcx), source_file_index) .expect("missing source file") - .decode(self); + .decode((self, tcx)); // We can't reuse an existing SourceFile, so allocate a new one // containing the information we need. @@ -1749,7 +1759,7 @@ impl<'a> CrateMetadataRef<'a> { // compiler is bootstrapped. try_to_translate_real_to_virtual( option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"), - &sess.opts.real_rust_source_base_dir, + &tcx.sess.opts.real_rust_source_base_dir, "library", &mut name, ); @@ -1760,7 +1770,7 @@ impl<'a> CrateMetadataRef<'a> { // with `remap-debuginfo = true`. try_to_translate_real_to_virtual( option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"), - &sess.opts.real_rustc_dev_source_base_dir, + &tcx.sess.opts.real_rustc_dev_source_base_dir, "compiler", &mut name, ); @@ -1772,7 +1782,7 @@ impl<'a> CrateMetadataRef<'a> { // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`. try_to_translate_virtual_to_real( option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"), - &sess.opts.real_rust_source_base_dir, + &tcx.sess.opts.real_rust_source_base_dir, &mut name, ); @@ -1783,11 +1793,11 @@ impl<'a> CrateMetadataRef<'a> { // the `rustc-dev` component in `Src::run` in `src/bootstrap/dist.rs`. try_to_translate_virtual_to_real( option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"), - &sess.opts.real_rustc_dev_source_base_dir, + &tcx.sess.opts.real_rustc_dev_source_base_dir, &mut name, ); - let local_version = sess.source_map().new_imported_source_file( + let local_version = tcx.sess.source_map().new_imported_source_file( name, src_hash, checksum_hash, @@ -1820,35 +1830,40 @@ impl<'a> CrateMetadataRef<'a> { .clone() } - fn get_attr_flags(self, index: DefIndex) -> AttrFlags { - self.root.tables.attr_flags.get(self, index) + fn get_attr_flags(self, tcx: TyCtxt<'_>, index: DefIndex) -> AttrFlags { + self.root.tables.attr_flags.get((self, tcx), index) } - fn get_intrinsic(self, index: DefIndex) -> Option { - self.root.tables.intrinsic.get(self, index).map(|d| d.decode(self)) + fn get_intrinsic(self, tcx: TyCtxt<'_>, index: DefIndex) -> Option { + self.root.tables.intrinsic.get((self, tcx), index).map(|d| d.decode((self, tcx))) } - fn get_doc_link_resolutions(self, index: DefIndex) -> DocLinkResMap { + fn get_doc_link_resolutions(self, tcx: TyCtxt<'_>, index: DefIndex) -> DocLinkResMap { self.root .tables .doc_link_resolutions - .get(self, index) + .get((self, tcx), index) .expect("no resolutions for a doc link") - .decode(self) + .decode((self, tcx)) } - fn get_doc_link_traits_in_scope(self, index: DefIndex) -> impl Iterator { + fn get_doc_link_traits_in_scope( + self, + tcx: TyCtxt<'_>, + index: DefIndex, + ) -> impl Iterator { self.root .tables .doc_link_traits_in_scope - .get(self, index) + .get((self, tcx), index) .expect("no traits in scope for a doc link") - .decode(self) + .decode((self, tcx)) } } impl CrateMetadata { pub(crate) fn new( + tcx: TyCtxt<'_>, cstore: &CStore, blob: MetadataBlob, root: CrateRoot, @@ -1897,11 +1912,14 @@ 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, tcx)) + .map(|incoherent_impls| { + (incoherent_impls.self_ty.decode((cref, tcx)), incoherent_impls.impls) + }) .collect(); cdata @@ -1994,13 +2012,14 @@ impl CrateMetadata { pub(crate) fn proc_macros_for_crate( &self, + tcx: TyCtxt<'_>, krate: CrateNum, cstore: &CStore, ) -> impl Iterator { gen move { for def_id in self.root.proc_macro_data.as_ref().into_iter().flat_map(move |data| { data.macros - .decode(CrateMetadataRef { cdata: self, cstore }) + .decode((CrateMetadataRef { cdata: self, cstore }, tcx)) .map(move |index| DefId { index, krate }) }) { yield def_id; diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 4831395f31641..ac4faae5a87a4 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::StableCrateId; 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]> { @@ -98,7 +99,7 @@ macro_rules! provide_one { .root .tables .$name - .get($cdata, $def_id.index) + .get(($cdata, $tcx), $def_id.index) .map(|lazy| lazy.decode(($cdata, $tcx))) .process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name))) } @@ -107,7 +108,7 @@ macro_rules! provide_one { ($tcx:ident, $def_id:ident, $other:ident, $cdata:ident, $name:ident => { table_defaulted_array }) => { provide_one! { $tcx, $def_id, $other, $cdata, $name => { - let lazy = $cdata.root.tables.$name.get($cdata, $def_id.index); + let lazy = $cdata.root.tables.$name.get(($cdata, $tcx), $def_id.index); let value = if lazy.is_default() { &[] as &[_] } else { @@ -125,7 +126,7 @@ macro_rules! provide_one { .root .tables .$name - .get($cdata, $def_id.index) + .get(($cdata, $tcx), $def_id.index) .process_decoded($tcx, || panic!("{:?} does not have a {:?}", $def_id, stringify!($name))) } } @@ -251,7 +252,7 @@ provide! { tcx, def_id, other, cdata, lookup_default_body_stability => { table } lookup_deprecation_entry => { table } params_in_repr => { table } - def_kind => { cdata.def_kind(def_id.index) } + def_kind => { cdata.def_kind(tcx, def_id.index) } impl_parent => { table } defaultness => { table_direct } constness => { table_direct } @@ -262,7 +263,7 @@ provide! { tcx, def_id, other, cdata, .root .tables .coerce_unsized_info - .get(cdata, def_id.index) + .get((cdata, tcx), def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) .process_decoded(tcx, || panic!("{def_id:?} does not have coerce_unsized_info"))) } mir_const_qualif => { table } @@ -278,7 +279,7 @@ provide! { tcx, def_id, other, cdata, .root .tables .eval_static_initializer - .get(cdata, def_id.index) + .get((cdata, tcx), def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) .unwrap_or_else(|| panic!("{def_id:?} does not have eval_static_initializer"))) } @@ -291,7 +292,7 @@ provide! { tcx, def_id, other, cdata, .root .tables .deduced_param_attrs - .get(cdata, def_id.index) + .get((cdata, tcx), def_id.index) .map(|lazy| { &*tcx.arena.alloc_from_iter(lazy.decode((cdata, tcx))) }) @@ -304,25 +305,25 @@ provide! { tcx, def_id, other, cdata, .root .tables .trait_impl_trait_tys - .get(cdata, def_id.index) + .get((cdata, tcx), def_id.index) .map(|lazy| lazy.decode((cdata, tcx))) .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys"))) } associated_types_for_impl_traits_in_trait_or_impl => { table } - visibility => { cdata.get_visibility(def_id.index) } - adt_def => { cdata.get_adt_def(def_id.index, tcx) } + visibility => { cdata.get_visibility(tcx, def_id.index) } + adt_def => { cdata.get_adt_def(tcx, def_id.index) } adt_destructor => { table } adt_async_destructor => { table } associated_item_def_ids => { - tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(def_id.index)) + tcx.arena.alloc_from_iter(cdata.get_associated_item_or_field_def_ids(tcx, def_id.index)) } - associated_item => { cdata.get_associated_item(def_id.index, tcx.sess) } + associated_item => { cdata.get_associated_item(tcx, def_id.index) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } - attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } - is_mir_available => { cdata.is_item_mir_available(def_id.index) } - is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) } + attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(tcx, def_id.index)) } + is_mir_available => { cdata.is_item_mir_available(tcx, def_id.index) } + is_ctfe_mir_available => { cdata.is_ctfe_mir_available(tcx, def_id.index) } cross_crate_inlinable => { table_direct } dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) } @@ -354,8 +355,8 @@ provide! { tcx, def_id, other, cdata, reachable_non_generics } - native_libraries => { cdata.get_native_libraries(tcx.sess).collect() } - foreign_modules => { cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect() } + native_libraries => { cdata.get_native_libraries(tcx).collect() } + foreign_modules => { cdata.get_foreign_modules(tcx).map(|m| (m.def_id, m)).collect() } crate_hash => { cdata.root.header.hash } crate_host_hash => { cdata.host_hash } crate_name => { cdata.root.header.name } @@ -363,23 +364,23 @@ provide! { tcx, def_id, other, cdata, extra_filename => { cdata.root.extra_filename.clone() } - traits => { tcx.arena.alloc_from_iter(cdata.get_traits()) } - trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls()) } + traits => { tcx.arena.alloc_from_iter(cdata.get_traits(tcx)) } + trait_impls_in_crate => { tcx.arena.alloc_from_iter(cdata.get_trait_impls(tcx)) } implementations_of_trait => { cdata.get_implementations_of_trait(tcx, other) } crate_incoherent_impls => { cdata.get_incoherent_impls(tcx, other) } dep_kind => { cdata.dep_kind } module_children => { - tcx.arena.alloc_from_iter(cdata.get_module_children(def_id.index, tcx.sess)) + tcx.arena.alloc_from_iter(cdata.get_module_children(tcx, def_id.index)) } - lib_features => { cdata.get_lib_features() } + lib_features => { cdata.get_lib_features(tcx) } stability_implications => { cdata.get_stability_implications(tcx).iter().copied().collect() } - stripped_cfg_items => { cdata.get_stripped_cfg_items(cdata.cnum, tcx) } - intrinsic_raw => { cdata.get_intrinsic(def_id.index) } + stripped_cfg_items => { cdata.get_stripped_cfg_items(tcx, cdata.cnum) } + intrinsic_raw => { cdata.get_intrinsic(tcx, def_id.index) } defined_lang_items => { cdata.get_lang_items(tcx) } - diagnostic_items => { cdata.get_diagnostic_items() } + diagnostic_items => { cdata.get_diagnostic_items(tcx) } missing_lang_items => { cdata.get_missing_lang_items(tcx) } missing_extern_crate_item => { @@ -387,20 +388,20 @@ provide! { tcx, def_id, other, cdata, } used_crate_source => { Arc::clone(&cdata.source) } - debugger_visualizers => { cdata.get_debugger_visualizers() } + debugger_visualizers => { cdata.get_debugger_visualizers(tcx) } - exportable_items => { tcx.arena.alloc_from_iter(cdata.get_exportable_items()) } - stable_order_of_exportable_impls => { tcx.arena.alloc(cdata.get_stable_order_of_exportable_impls().collect()) } + exportable_items => { tcx.arena.alloc_from_iter(cdata.get_exportable_items(tcx)) } + stable_order_of_exportable_impls => { tcx.arena.alloc(cdata.get_stable_order_of_exportable_impls(tcx).collect()) } exported_non_generic_symbols => { cdata.exported_non_generic_symbols(tcx) } exported_generic_symbols => { cdata.exported_generic_symbols(tcx) } crate_extern_paths => { cdata.source().paths().cloned().collect() } - expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) } - default_field => { cdata.get_default_field(def_id.index) } - is_doc_hidden => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) } - doc_link_resolutions => { tcx.arena.alloc(cdata.get_doc_link_resolutions(def_id.index)) } + expn_that_defined => { cdata.get_expn_that_defined(tcx, def_id.index) } + default_field => { cdata.get_default_field(tcx, def_id.index) } + is_doc_hidden => { cdata.get_attr_flags(tcx,def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) } + doc_link_resolutions => { tcx.arena.alloc(cdata.get_doc_link_resolutions(tcx, def_id.index)) } doc_link_traits_in_scope => { - tcx.arena.alloc_from_iter(cdata.get_doc_link_traits_in_scope(def_id.index)) + tcx.arena.alloc_from_iter(cdata.get_doc_link_traits_in_scope(tcx, def_id.index)) } anon_const_kind => { table } const_of_item => { table } @@ -550,38 +551,38 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) { } impl CStore { - pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> { - self.get_crate_data(def.krate).get_ctor(def.index) + pub fn ctor_untracked(&self, tcx: TyCtxt<'_>, def: DefId) -> Option<(CtorKind, DefId)> { + self.get_crate_data(def.krate).get_ctor(tcx, def.index) } - pub fn load_macro_untracked(&self, id: DefId, tcx: TyCtxt<'_>) -> LoadedMacro { + pub fn load_macro_untracked(&self, tcx: TyCtxt<'_>, id: DefId) -> LoadedMacro { let sess = tcx.sess; let _prof_timer = sess.prof.generic_activity("metadata_load_macro"); let data = self.get_crate_data(id.krate); if data.root.is_proc_macro_crate() { - LoadedMacro::ProcMacro(data.load_proc_macro(id.index, tcx)) + LoadedMacro::ProcMacro(data.load_proc_macro(tcx, id.index)) } else { LoadedMacro::MacroDef { - def: data.get_macro(id.index, sess), - ident: data.item_ident(id.index, sess), - attrs: data.get_item_attrs(id.index, sess).collect(), - span: data.get_span(id.index, sess), + def: data.get_macro(tcx, id.index), + ident: data.item_ident(tcx, id.index), + attrs: data.get_item_attrs(tcx, id.index).collect(), + span: data.get_span(tcx, id.index), edition: data.root.edition, } } } - pub fn def_span_untracked(&self, def_id: DefId, sess: &Session) -> Span { - self.get_crate_data(def_id.krate).get_span(def_id.index, sess) + pub fn def_span_untracked(&self, tcx: TyCtxt<'_>, def_id: DefId) -> Span { + self.get_crate_data(def_id.krate).get_span(tcx, def_id.index) } - pub fn def_kind_untracked(&self, def: DefId) -> DefKind { - self.get_crate_data(def.krate).def_kind(def.index) + pub fn def_kind_untracked(&self, tcx: TyCtxt<'_>, def: DefId) -> DefKind { + self.get_crate_data(def.krate).def_kind(tcx, def.index) } - pub fn expn_that_defined_untracked(&self, def_id: DefId, sess: &Session) -> ExpnId { - self.get_crate_data(def_id.krate).get_expn_that_defined(def_id.index, sess) + pub fn expn_that_defined_untracked(&self, tcx: TyCtxt<'_>, def_id: DefId) -> ExpnId { + self.get_crate_data(def_id.krate).get_expn_that_defined(tcx, def_id.index) } /// Only public-facing way to traverse all the definitions in a non-local crate. @@ -593,20 +594,20 @@ impl CStore { pub fn get_proc_macro_quoted_span_untracked( &self, + tcx: TyCtxt<'_>, cnum: CrateNum, id: usize, - sess: &Session, ) -> Span { - self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess) + self.get_crate_data(cnum).get_proc_macro_quoted_span(tcx, id) } - pub fn set_used_recursively(&mut self, cnum: CrateNum) { + pub fn set_used_recursively(&mut self, tcx: TyCtxt<'_>, cnum: CrateNum) { let cmeta = self.get_crate_data_mut(cnum); if !cmeta.used { cmeta.used = true; let dependencies = mem::take(&mut cmeta.dependencies); for &dep_cnum in &dependencies { - self.set_used_recursively(dep_cnum); + self.set_used_recursively(tcx, dep_cnum); } self.get_crate_data_mut(cnum).dependencies = dependencies; } @@ -699,13 +700,13 @@ fn provide_cstore_hooks(providers: &mut Providers) { providers.hooks.expn_hash_to_expn_id = |tcx, cnum, index_guess, hash| { let cstore = CStore::from_tcx(tcx); - cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx.sess, index_guess, hash) + cstore.get_crate_data(cnum).expn_hash_to_expn_id(tcx, index_guess, hash) }; providers.hooks.import_source_files = |tcx, cnum| { let cstore = CStore::from_tcx(tcx); let cdata = cstore.get_crate_data(cnum); for file_index in 0..cdata.root.source_map.size() { - cdata.imported_source_file(file_index as u32, tcx.sess); + cdata.imported_source_file(tcx, file_index as u32); } }; } 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 a17b3e1047d09..949d7630f6736 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 4085fd5e70f16..94bba94456102 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 ac042c2ca75de..8ac1dd83ee5df 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,7 @@ 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, LazyDecodable, MetadataEncodable, TyDecodable, TyEncodable, }; use rustc_middle::metadata::ModChild; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; @@ -187,7 +187,7 @@ type SyntaxContextTable = LazyTable>>; type ExpnDataTable = LazyTable>>; type ExpnHashTable = LazyTable>>; -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct ProcMacroData { proc_macro_decls_static: DefIndex, stability: Option, @@ -201,7 +201,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, @@ -236,7 +236,7 @@ pub(crate) struct CrateHeader { /// compilation session. If we were to serialize a proc-macro crate like /// a normal crate, much of what we serialized would be unusable in addition /// to being unused. -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct CrateRoot { /// A header used to detect if this is the right crate to load. header: CrateHeader, @@ -323,7 +323,7 @@ impl RawDefId { } } -#[derive(Encodable, Decodable)] +#[derive(Encodable, BlobDecodable)] pub(crate) struct CrateDep { pub name: Symbol, pub hash: Svh, @@ -333,15 +333,15 @@ pub(crate) struct CrateDep { pub is_private: bool, } -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct TraitImpls { trait_id: (u32, DefIndex), impls: LazyArray<(DefIndex, Option)>, } -#[derive(MetadataEncodable, MetadataDecodable)] +#[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct IncoherentImpls { - self_ty: SimplifiedType, + self_ty: LazyValue, impls: LazyArray, } @@ -351,7 +351,7 @@ macro_rules! define_tables { - defaulted: $($name1:ident: Table<$IDX1:ty, $T1:ty>,)+ - optional: $($name2:ident: Table<$IDX2:ty, $T2:ty>,)+ ) => { - #[derive(MetadataEncodable, MetadataDecodable)] + #[derive(MetadataEncodable, LazyDecodable)] pub(crate) struct LazyTables { $($name1: LazyTable<$IDX1, $T1>,)+ $($name2: LazyTable<$IDX2, Option<$T2>>,)+ diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 4ce313f32a75d..3b5a38181d58b 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::Metadata; use crate::rmeta::*; pub(super) trait IsDefault: Default { @@ -522,7 +523,7 @@ 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: Metadata<'a>>(&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 9091d492c26b2..5739d132b66ca 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 e8952d0492d1e..c882d5d499bd1 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 d3e0fbb955c4d..b4c20d7cadf9f 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_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index cd12d5ad10cf7..26658aef3359f 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -141,7 +141,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // Query `def_kind` is not used because query system overhead is too expensive here. - let def_kind = self.cstore().def_kind_untracked(def_id); + let def_kind = self.cstore().def_kind_untracked(self.tcx, def_id); if def_kind.is_module_like() { let parent = self .tcx @@ -149,7 +149,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .map(|parent_id| self.get_nearest_non_block_module(parent_id)); // Query `expn_that_defined` is not used because // hashing spans in its result is expensive. - let expn_id = self.cstore().expn_that_defined_untracked(def_id, self.tcx.sess); + let expn_id = self.cstore().expn_that_defined_untracked(self.tcx, def_id); return Some(self.new_extern_module( parent, ModuleKind::Def(def_kind, def_id, Some(self.tcx.item_name(def_id))), @@ -196,7 +196,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match def_id.as_local() { Some(local_def_id) => self.local_macro_map[&local_def_id], None => *self.extern_macro_map.borrow_mut().entry(def_id).or_insert_with(|| { - let loaded_macro = self.cstore().load_macro_untracked(def_id, self.tcx); + let loaded_macro = self.cstore().load_macro_untracked(self.tcx, def_id); let macro_data = match loaded_macro { LoadedMacro::MacroDef { def, ident, attrs, span, edition } => { self.compile_macro(&def, ident, &attrs, span, ast::DUMMY_NODE_ID, edition) @@ -213,7 +213,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// find them for suggestions. pub(crate) fn register_macros_for_all_crates(&mut self) { if !self.all_crate_macros_already_registered { - for def_id in self.cstore().all_proc_macro_def_ids() { + for def_id in self.cstore().all_proc_macro_def_ids(self.tcx) { self.get_macro_by_def_id(def_id); } self.all_crate_macros_already_registered = true; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index f59b5a0aad9a7..e38d4370d5d25 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -1235,7 +1235,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let struct_ctor = match def_id.as_local() { Some(def_id) => self.struct_constructors.get(&def_id).cloned(), None => { - let ctor = self.cstore().ctor_untracked(def_id); + let ctor = self.cstore().ctor_untracked(self.tcx(), def_id); ctor.map(|(ctor_kind, ctor_def_id)| { let ctor_res = Res::Def( DefKind::Ctor(rustc_hir::def::CtorOf::Struct, ctor_kind), diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3ab6c7dcc0066..71baef458bbfd 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2024,7 +2024,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { let struct_ctor = match def_id.as_local() { Some(def_id) => self.r.struct_constructors.get(&def_id).cloned(), None => { - let ctor = self.r.cstore().ctor_untracked(def_id); + let ctor = self.r.cstore().ctor_untracked(self.r.tcx(), def_id); ctor.map(|(ctor_kind, ctor_def_id)| { let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ed47f3124f939..35d54615772b6 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -2316,7 +2316,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { match def_id.as_local() { Some(def_id) => self.tcx.source_span(def_id), // Query `def_span` is not used because hashing its result span is expensive. - None => self.cstore().def_span_untracked(def_id, self.tcx.sess), + None => self.cstore().def_span_untracked(self.tcx(), def_id), } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 10a0078547ad9..6bba985d87dd7 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -477,7 +477,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn get_proc_macro_quoted_span(&self, krate: CrateNum, id: usize) -> Span { - self.cstore().get_proc_macro_quoted_span_untracked(krate, id, self.tcx.sess) + self.cstore().get_proc_macro_quoted_span_untracked(self.tcx, krate, id) } fn declare_proc_macro(&mut self, id: NodeId) { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f97a29e064b65..9b19961fcee4e 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 30f6256a75efa..8aef4b179f883 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 872a48efa3661..d9792142a884d 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 77f01548bca2b..484e626d4638a 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 28335734f4dec..a27c5f62c1e5d 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 31f82860b73d8..6a359c5f4656c 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1296,28 +1296,38 @@ impl Encodable for AttrId { } } +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: Decoder { +/// +/// Specifically for metadata, an important note is that spans can only be decoded once +/// some other metadata is already read. +/// Spans have to be properly mapped into the decoding crate's sourcemap, +/// and crate numbers have to be converted sometimes. +/// This can only be done once the `CrateRoot` is available. +/// +/// As such, some methods that used to be in the `SpanDecoder` trait +/// are now in the `BlobDecoder` trait. This hierarchy is not mirrored for `Encoder`s. +/// `BlobDecoder` has methods for deserializing types that are more complex than just those +/// that can be decoded with `Decoder`, but which can be decoded on their own, *before* any other metadata is. +/// Importantly, that means that types that can be decoded with `BlobDecoder` can show up in the crate root. +/// The place where this distinction is relevant is in `rustc_metadata` where metadata is decoded using either the +/// `MetadataDecodeContext` or the `BlobDecodeContext`. +pub trait SpanDecoder: BlobDecoder { fn decode_span(&mut self) -> Span; - fn decode_symbol(&mut self) -> Symbol; - fn decode_byte_symbol(&mut self) -> ByteSymbol; 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) - } - +impl BlobDecoder for MemDecoder<'_> { fn decode_symbol(&mut self) -> Symbol { Symbol::intern(self.read_str()) } @@ -1326,6 +1336,19 @@ impl SpanDecoder for MemDecoder<'_> { 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); + let hi = Decodable::decode(self); + + Span::new(lo, hi, SyntaxContext::root(), None) + } + fn decode_expn_id(&mut self) -> ExpnId { panic!("cannot decode `ExpnId` with `MemDecoder`"); } @@ -1338,10 +1361,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 +1376,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 +1406,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 424026bdceab8..c76e345bb7b64 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, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 189d3a70ad626..849df566b4bd0 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -239,7 +239,7 @@ pub(crate) fn get_item_path(tcx: TyCtxt<'_>, def_id: DefId, kind: ItemType) -> V // Check to see if it is a macro 2.0 or built-in macro // More information in . if matches!( - CStore::from_tcx(tcx).load_macro_untracked(def_id, tcx), + CStore::from_tcx(tcx).load_macro_untracked(tcx, def_id), LoadedMacro::MacroDef { def, .. } if !def.macro_rules ) { once(crate_name).chain(relative).collect() @@ -772,7 +772,7 @@ fn build_macro( name: Symbol, macro_kinds: MacroKinds, ) -> clean::ItemKind { - match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) { + match CStore::from_tcx(cx.tcx).load_macro_untracked(cx.tcx, def_id) { // FIXME: handle attributes and derives that aren't proc macros, and macros with multiple // kinds LoadedMacro::MacroDef { def, .. } => match macro_kinds {