Auto merge of #149455 - jdonszelmann:metadata-decoding-s, r=WaffleLapkin

Remove unwraps from metadata decoding: introduce `BlobDecoder`

r? `@oli-obk`
This commit is contained in:
bors
2025-12-08 09:41:00 +00:00
29 changed files with 728 additions and 610 deletions
+4 -4
View File
@@ -11,7 +11,7 @@
use rustc_data_structures::unord::UnordMap;
use rustc_hashes::Hash64;
use rustc_index::IndexVec;
use rustc_macros::{Decodable, Encodable};
use rustc_macros::{BlobDecodable, Decodable, Encodable};
use rustc_span::{Symbol, kw, sym};
use tracing::{debug, instrument};
@@ -127,7 +127,7 @@ pub struct Definitions {
/// A unique identifier that we can use to lookup a definition
/// precisely. It combines the index of the definition's parent (if
/// any) with a `DisambiguatedDefPathData`.
#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable)]
#[derive(Copy, Clone, PartialEq, Debug, Encodable, BlobDecodable)]
pub struct DefKey {
/// The parent path.
pub parent: Option<DefIndex>,
@@ -176,7 +176,7 @@ pub fn get_opt_name(&self) -> Option<Symbol> {
/// 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 @@ pub fn to_filename_friendly_no_crate(&self) -> String {
}
/// 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.
+2 -2
View File
@@ -10,7 +10,7 @@
use rustc_ast::attr::AttributeExt;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_macros::{BlobDecodable, Encodable, HashStable_Generic};
use rustc_span::{Span, Symbol, kw, sym};
use crate::def_id::DefId;
@@ -75,7 +75,7 @@ macro_rules! language_item_table {
$( $(#[$attr:meta])* $variant:ident, $module:ident :: $name:ident, $method:ident, $target:expr, $generics:expr; )*
) => {
/// A representation of all the valid lang items in Rust.
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Encodable, BlobDecodable)]
pub enum LangItem {
$(
#[doc = concat!("The `", stringify!($name), "` lang item.")]
+5 -5
View File
@@ -1,6 +1,6 @@
use std::num::NonZero;
use rustc_macros::{Decodable, Encodable, HashStable_Generic, PrintAttribute};
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic, PrintAttribute};
use rustc_span::{ErrorGuaranteed, Symbol, sym};
use crate::RustcVersion;
@@ -21,7 +21,7 @@
///
/// - `#[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 @@ pub fn is_const_stable(&self) -> bool {
}
/// 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 @@ pub fn stable_since(&self) -> Option<StableSince> {
}
}
#[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,
+2 -2
View File
@@ -4,12 +4,12 @@
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,
+71 -5
View File
@@ -72,14 +72,80 @@ pub fn extension(attr: TokenStream, input: TokenStream) -> TokenStream {
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<D> 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<D> 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<D>` 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<D> 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<D> 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<D> 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).
+13 -6
View File
@@ -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)
+5 -3
View File
@@ -276,8 +276,9 @@ pub(crate) fn iter_crate_data(&self) -> impl Iterator<Item = (CrateNum, &CrateMe
.filter_map(|(cnum, data)| data.as_deref().map(|data| (cnum, data)))
}
pub fn all_proc_macro_def_ids(&self) -> impl Iterator<Item = DefId> {
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<Item = DefId> {
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<CrateNum>, cnum: CrateNum) {
@@ -683,6 +684,7 @@ fn register_crate<'tcx>(
};
let crate_metadata = CrateMetadata::new(
tcx,
self,
metadata,
crate_root,
@@ -778,7 +780,7 @@ fn resolve_crate<'tcx>(
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) => {
+451 -432
View File
@@ -1,6 +1,7 @@
// Decoding metadata from a single crate's metadata
use std::iter::TrustedLen;
use std::ops::{Deref, DerefMut};
use std::path::{Path, PathBuf};
use std::sync::{Arc, OnceLock};
use std::{io, mem};
@@ -28,12 +29,12 @@
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,208 +155,23 @@ struct ImportedSourceFile {
translated_source_file: Arc<rustc_span::SourceFile>,
}
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<CrateMetadataRef<'a>>,
blob: &'a MetadataBlob,
sess: Option<&'tcx Session>,
tcx: Option<TyCtxt<'tcx>>,
lazy_state: LazyState,
// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
alloc_decoding_session: Option<AllocDecodingSession<'a>>,
}
/// Abstract over the various ways one can create metadata decoders.
pub(super) trait Metadata<'a, 'tcx>: Copy {
fn blob(self) -> &'a MetadataBlob;
fn cdata(self) -> Option<CrateMetadataRef<'a>> {
None
}
fn sess(self) -> Option<&'tcx Session> {
None
}
fn tcx(self) -> Option<TyCtxt<'tcx>> {
None
}
fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> {
let tcx = self.tcx();
DecodeContext {
// FIXME: This unwrap should never panic because we check that it won't when creating
// `MetadataBlob`. Ideally we'd just have a `MetadataDecoder` and hand out subslices of
// it as we do elsewhere in the compiler using `MetadataDecoder::split_at`. But we own
// the data for the decoder so holding onto the `MemDecoder` too would make us a
// self-referential struct which is downright goofy because `MetadataBlob` is already
// self-referential. Probably `MemDecoder` should contain an `OwnedSlice`, but that
// demands a significant refactoring due to our crate graph.
opaque: MemDecoder::new(self.blob(), pos).unwrap(),
cdata: self.cdata(),
blob: self.blob(),
sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
tcx,
lazy_state: LazyState::NoNode,
alloc_decoding_session: self
.cdata()
.map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()),
}
}
}
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<CrateMetadataRef<'a>> {
Some(self)
}
}
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<CrateMetadataRef<'a>> {
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<CrateMetadataRef<'a>> {
Some(self.0)
}
#[inline]
fn tcx(self) -> Option<TyCtxt<'tcx>> {
Some(self.1)
}
}
impl<T: ParameterizedOverTcx> LazyValue<T> {
#[inline]
fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(self, metadata: M) -> T::Value<'tcx>
where
T::Value<'tcx>: Decodable<DecodeContext<'a, 'tcx>>,
{
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
T::Value::decode(&mut dcx)
}
}
struct DecodeIterator<'a, 'tcx, T> {
elem_counter: std::ops::Range<usize>,
dcx: DecodeContext<'a, 'tcx>,
_phantom: PhantomData<fn() -> T>,
}
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Iterator for DecodeIterator<'a, 'tcx, T> {
type Item = T;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.elem_counter.next().map(|_| T::decode(&mut self.dcx))
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.elem_counter.size_hint()
}
}
impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> ExactSizeIterator
for DecodeIterator<'a, 'tcx, T>
{
fn len(&self) -> usize {
self.elem_counter.len()
}
}
unsafe impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> TrustedLen
for DecodeIterator<'a, 'tcx, T>
{
}
impl<T: ParameterizedOverTcx> LazyArray<T> {
#[inline]
fn decode<'a, 'tcx, M: Metadata<'a, 'tcx>>(
self,
metadata: M,
) -> DecodeIterator<'a, 'tcx, T::Value<'tcx>>
where
T::Value<'tcx>: Decodable<DecodeContext<'a, 'tcx>>,
{
let mut dcx = metadata.decoder(self.position.get());
dcx.lazy_state = LazyState::NodeStart(self.position);
DecodeIterator { elem_counter: (0..self.num_elems), dcx, _phantom: PhantomData }
}
}
impl<'a, 'tcx> DecodeContext<'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
}
#[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<T>(&mut self, f: impl Fn(NonZero<usize>) -> T) -> T {
let distance = self.read_usize();
let position = match self.lazy_state {
LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
LazyState::NodeStart(start) => {
let start = start.get();
assert!(distance <= start);
start - distance
}
LazyState::Previous(last_pos) => last_pos.get() + distance,
};
let position = NonZero::new(position).unwrap();
self.lazy_state = LazyState::Previous(position);
f(position)
}
/// 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<T>(&mut self) -> LazyValue<T> {
self.read_lazy_offset_then(|pos| LazyValue::from_position(pos))
@@ -370,8 +186,182 @@ fn read_lazy_table<I, T>(&mut self, width: usize, len: usize) -> LazyTable<I, T>
}
#[inline]
fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
self.opaque.read_raw_bytes(len)
fn read_lazy_offset_then<T>(&mut self, f: impl Fn(NonZero<usize>) -> T) -> T {
let distance = self.read_usize();
let position = match self.get_lazy_state() {
LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
LazyState::NodeStart(start) => {
let start = start.get();
assert!(distance <= start);
start - distance
}
LazyState::Previous(last_pos) => last_pos.get() + distance,
};
let position = NonZero::new(position).unwrap();
self.set_lazy_state(LazyState::Previous(position));
f(position)
}
}
impl<'a> LazyDecoder for BlobDecodeContext<'a> {
fn set_lazy_state(&mut self, state: LazyState) {
self.lazy_state = state;
}
fn get_lazy_state(&self) -> LazyState {
self.lazy_state
}
}
/// This is the decode context used when crate metadata was already read.
/// Decoding of some types, like `Span` require some information to already been read.
/// 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: AllocDecodingSession<'a>,
}
impl<'a, 'tcx> LazyDecoder for MetadataDecodeContext<'a, 'tcx> {
fn set_lazy_state(&mut self, state: LazyState) {
self.lazy_state = state;
}
fn get_lazy_state(&self) -> LazyState {
self.lazy_state
}
}
impl<'a, 'tcx> DerefMut for MetadataDecodeContext<'a, 'tcx> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.blob_decoder
}
}
impl<'a, 'tcx> Deref for MetadataDecodeContext<'a, 'tcx> {
type Target = BlobDecodeContext<'a>;
fn deref(&self) -> &Self::Target {
&self.blob_decoder
}
}
pub(super) trait 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
// the data for the decoder so holding onto the `MemDecoder` too would make us a
// self-referential struct which is downright goofy because `MetadataBlob` is already
// self-referential. Probably `MemDecoder` should contain an `OwnedSlice`, but that
// demands a significant refactoring due to our crate graph.
opaque: MemDecoder::new(self, pos).unwrap(),
lazy_state: LazyState::NoNode,
blob: self.blob(),
}
}
}
impl<'a, 'tcx> Metadata<'a> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) {
type Context = MetadataDecodeContext<'a, 'tcx>;
fn blob(self) -> &'a MetadataBlob {
&self.0.cdata.blob
}
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<T: ParameterizedOverTcx> LazyValue<T> {
#[inline]
fn decode<'a, 'tcx, M: Metadata<'a>>(self, metadata: M) -> T::Value<'tcx>
where
T::Value<'tcx>: Decodable<M::Context>,
{
let mut dcx = metadata.decoder(self.position.get());
dcx.set_lazy_state(LazyState::NodeStart(self.position));
T::Value::decode(&mut dcx)
}
}
struct DecodeIterator<T, D> {
elem_counter: std::ops::Range<usize>,
dcx: D,
_phantom: PhantomData<fn() -> T>,
}
impl<D: Decoder, T: Decodable<D>> Iterator for DecodeIterator<T, D> {
type Item = T;
#[inline(always)]
fn next(&mut self) -> Option<Self::Item> {
self.elem_counter.next().map(|_| T::decode(&mut self.dcx))
}
#[inline(always)]
fn size_hint(&self) -> (usize, Option<usize>) {
self.elem_counter.size_hint()
}
}
impl<D: Decoder, T: Decodable<D>> ExactSizeIterator for DecodeIterator<T, D> {
fn len(&self) -> usize {
self.elem_counter.len()
}
}
unsafe impl<D: Decoder, T: Decodable<D>> TrustedLen for DecodeIterator<T, D> {}
impl<T: ParameterizedOverTcx> LazyArray<T> {
#[inline]
fn decode<'a, 'tcx, M: Metadata<'a>>(
self,
metadata: M,
) -> DecodeIterator<T::Value<'tcx>, M::Context>
where
T::Value<'tcx>: Decodable<M::Context>,
{
let mut dcx = metadata.decoder(self.position.get());
dcx.set_lazy_state(LazyState::NodeStart(self.position));
DecodeIterator { elem_counter: (0..self.num_elems), dcx, _phantom: PhantomData }
}
}
impl<'a, 'tcx> MetadataDecodeContext<'a, 'tcx> {
#[inline]
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
}
fn decode_symbol_or_byte_symbol<S>(
@@ -397,21 +387,21 @@ fn decode_symbol_or_byte_symbol<S>(
}
}
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<F>(&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 @@ fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
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<DecodeContext<'a, 'tcx>> for ExpnIndex {
impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for ExpnIndex {
#[inline]
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ExpnIndex {
fn decode(d: &mut MetadataDecodeContext<'a, 'tcx>) -> ExpnIndex {
ExpnIndex::from_u32(d.read_u32())
}
}
impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> {
impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> {
fn decode_attr_id(&mut self) -> rustc_span::AttrId {
let sess = self.sess.expect("can't decode AttrId without Session");
sess.psess.attr_id_generator.mk_attr_id()
self.tcx.sess.psess.attr_id_generator.mk_attr_id()
}
fn decode_crate_num(&mut self) -> CrateNum {
@@ -462,23 +448,13 @@ fn decode_crate_num(&mut self) -> CrateNum {
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 @@ fn decode_syntax_context(&mut self) -> SyntaxContext {
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 @@ fn decode_expn_id(&mut self) -> ExpnId {
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 @@ fn decode_span(&mut self) -> Span {
};
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 @@ fn decode_byte_symbol(&mut self) -> ByteSymbol {
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SpanData {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SpanData {
impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for SpanData {
fn decode(decoder: &mut MetadataDecodeContext<'a, 'tcx>) -> SpanData {
let tag = SpanTag::decode(decoder);
let ctxt = tag.context().unwrap_or_else(|| SyntaxContext::decode(decoder));
@@ -587,12 +575,7 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> 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 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> 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 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> 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 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SpanData {
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for &'tcx [(ty::Clause<'tcx>, Span)] {
fn decode(d: &mut MetadataDecodeContext<'a, 'tcx>) -> Self {
ty::codec::RefDecodable::decode(d)
}
}
impl<'a, 'tcx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyValue<T> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
impl<D: LazyDecoder, T> Decodable<D> for LazyValue<T> {
fn decode(decoder: &mut D) -> Self {
decoder.read_lazy()
}
}
impl<'a, 'tcx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyArray<T> {
impl<D: LazyDecoder, T> Decodable<D> for LazyArray<T> {
#[inline]
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
fn decode(decoder: &mut D) -> Self {
let len = decoder.read_usize();
if len == 0 { LazyArray::default() } else { decoder.read_lazy_array(len) }
}
}
impl<'a, 'tcx, I: Idx, T> Decodable<DecodeContext<'a, 'tcx>> for LazyTable<I, T> {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
impl<I: Idx, D: LazyDecoder, T> Decodable<D> for LazyTable<I, T> {
fn decode(decoder: &mut D) -> Self {
let width = decoder.read_usize();
let len = decoder.read_usize();
decoder.read_lazy_table(width, len)
}
}
implement_ty_decoder!(DecodeContext<'a, 'tcx>);
mod meta {
use super::*;
implement_ty_decoder!(MetadataDecodeContext<'a, 'tcx>);
}
mod blob {
use super::*;
implement_ty_decoder!(BlobDecodeContext<'a>);
}
impl MetadataBlob {
pub(crate) fn check_compatibility(
&self,
cfg_version: &'static str,
) -> Result<(), Option<String>> {
if !self.blob().starts_with(METADATA_HEADER) {
if self.blob().starts_with(b"rust") {
if !self.starts_with(METADATA_HEADER) {
if self.starts_with(b"rust") {
return Err(Some("<unknown rustc version>".to_owned()));
}
return Err(None);
@@ -731,7 +720,7 @@ pub(crate) fn check_compatibility(
fn root_pos(&self) -> NonZero<usize> {
let offset = METADATA_HEADER.len();
let pos_bytes = self.blob()[offset..][..8].try_into().unwrap();
let pos_bytes = self[offset..][..8].try_into().unwrap();
let pos = u64::from_le_bytes(pos_bytes);
NonZero::new(pos as usize).unwrap()
}
@@ -978,7 +967,7 @@ fn missing(self, descr: &str, id: DefIndex) -> ! {
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 @@ fn raw_proc_macro(self, id: DefIndex) -> &'a ProcMacro {
.as_ref()
.unwrap()
.macros
.decode(self)
.decode((self, tcx))
.position(|i| i == id)
.unwrap();
&self.raw_proc_macros.unwrap()[pos]
@@ -1009,20 +998,20 @@ fn item_name(self, item_index: DefIndex) -> Symbol {
self.opt_item_name(item_index).expect("no encoded ident for item")
}
fn opt_item_ident(self, item_index: DefIndex, sess: &Session) -> Option<Ident> {
fn opt_item_ident(self, tcx: TyCtxt<'_>, item_index: DefIndex) -> Option<Ident> {
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 @@ pub(super) fn map_encoded_cnum_to_current(self, cnum: CrateNum) -> CrateNum {
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::<Vec<_>>();
@@ -1067,11 +1056,11 @@ fn load_proc_macro<'tcx>(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtensi
};
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 @@ fn load_proc_macro<'tcx>(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> SyntaxExtensi
fn get_variant(
self,
tcx: TyCtxt<'_>,
kind: DefKind,
index: DefIndex,
parent_did: DefId,
@@ -1093,7 +1083,8 @@ fn get_variant(
_ => 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 @@ fn get_variant(
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 @@ fn get_variant(
)
}
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 @@ fn get_adt_def<'tcx>(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'
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 @@ fn get_adt_def<'tcx>(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::AdtDef<'
)
}
fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {
fn get_visibility(self, tcx: TyCtxt<'_>, id: DefIndex) -> Visibility<DefId> {
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<DefId> {
self.root.tables.default_fields.get(self, id).map(|d| d.decode(self))
fn get_default_field(self, tcx: TyCtxt<'_>, id: DefIndex) -> Option<DefId> {
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<DebuggerVisualizerFile> {
self.root.debugger_visualizers.decode(self).collect::<Vec<_>>()
fn get_debugger_visualizers(self, tcx: TyCtxt<'_>) -> Vec<DebuggerVisualizerFile> {
self.root.debugger_visualizers.decode((self, tcx)).collect::<Vec<_>>()
}
/// 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 @@ fn get_lib_features(self) -> LibFeatures {
/// 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 @@ fn get_lang_items<'tcx>(self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] {
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 @@ fn get_stripped_cfg_items<'tcx>(
}
/// 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 @@ fn get_diagnostic_items(self) -> DiagnosticItems {
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 @@ fn get_mod_child(self, id: DefIndex, sess: &Session) -> ModChild {
/// 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<Item = ModChild> {
fn get_module_children(self, tcx: TyCtxt<'_>, id: DefIndex) -> impl Iterator<Item = ModChild> {
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 @@ fn get_module_children(
}
}
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<Item = DefId> {
fn get_associated_item_or_field_def_ids(
self,
tcx: TyCtxt<'_>,
id: DefIndex,
) -> impl Iterator<Item = DefId> {
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 @@ fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem {
}
_ => 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<Item = hir::Attribute> {
fn get_item_attrs(self, tcx: TyCtxt<'_>, id: DefIndex) -> impl Iterator<Item = hir::Attribute> {
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 @@ fn get_item_attrs(
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 @@ fn get_inherent_implementations_for_type<'tcx>(
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<Item = DefId> {
self.root.traits.decode(self).map(move |index| self.local_def_id(index))
fn get_traits(self, tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> {
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<Item = DefId> {
fn get_trait_impls(self, tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> {
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 @@ fn get_implementations_of_trait<'tcx>(
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 @@ fn get_implementations_of_trait<'tcx>(
}
}
fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> {
self.root.native_libraries.decode((self, sess))
fn get_native_libraries(self, tcx: TyCtxt<'_>) -> impl Iterator<Item = NativeLib> {
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<Item = ForeignModule> {
self.root.foreign_modules.decode((self, sess))
fn get_foreign_modules(self, tcx: TyCtxt<'_>) -> impl Iterator<Item = ForeignModule> {
self.root.foreign_modules.decode((self, tcx))
}
fn get_dylib_dependency_formats<'tcx>(
@@ -1466,25 +1463,30 @@ fn get_dylib_dependency_formats<'tcx>(
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<Item = DefId> {
self.root.exportable_items.decode(self).map(move |index| self.local_def_id(index))
fn get_exportable_items(self, tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> {
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<Item = (DefId, usize)> {
fn get_stable_order_of_exportable_impls(
self,
tcx: TyCtxt<'_>,
) -> impl Iterator<Item = (DefId, usize)> {
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 @@ fn exported_generic_symbols<'tcx>(
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 @@ fn get_macro(self, id: DefIndex, sess: &Session) -> ast::MacroDef {
#[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 @@ fn def_path_hash(self, index: DefIndex) -> DefPathHash {
// 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 @@ fn def_path_hash_to_def_index(self, hash: DefPathHash) -> Option<DefIndex> {
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 @@ fn expn_hash_to_expn_id(self, sess: &Session, index_guess: u32, hash: ExpnHash)
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 @@ fn expn_hash_to_expn_id(self, sess: &Session, index_guess: u32, hash: ExpnHash)
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 @@ fn expn_hash_to_expn_id(self, sess: &Session, index_guess: u32, hash: ExpnHash)
///
/// 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<PathBuf>,
path: Option<&'a Path>,
) -> Option<&'a Path> {
@@ -1613,13 +1622,13 @@ fn filter<'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 @@ fn filter<'a>(
real_source_base_dir: &Option<PathBuf>,
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 @@ fn filter<'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 @@ fn filter<'a>(
real_source_base_dir: &Option<PathBuf>,
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 @@ fn filter<'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 @@ fn filter<'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 @@ fn filter<'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 @@ fn filter<'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 @@ fn filter<'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 @@ fn filter<'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<ty::IntrinsicDef> {
self.root.tables.intrinsic.get(self, index).map(|d| d.decode(self))
fn get_intrinsic(self, tcx: TyCtxt<'_>, index: DefIndex) -> Option<ty::IntrinsicDef> {
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<Item = DefId> {
fn get_doc_link_traits_in_scope(
self,
tcx: TyCtxt<'_>,
index: DefIndex,
) -> impl Iterator<Item = DefId> {
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 @@ pub(crate) fn new(
};
// 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 @@ pub(crate) fn is_proc_macro_crate(&self) -> bool {
pub(crate) fn proc_macros_for_crate(
&self,
tcx: TyCtxt<'_>,
krate: CrateNum,
cstore: &CStore,
) -> impl Iterator<Item = DefId> {
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;
@@ -15,12 +15,13 @@
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 @@ fn process_decoded(self, _tcx: TyCtxt<'_>, _err: impl Fn() -> !) -> Result<Optio
}
}
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>> ProcessQueryValue<'tcx, &'tcx [T]>
for Option<DecodeIterator<'a, 'tcx, T>>
impl<'tcx, D: Decoder, T: Copy + Decodable<D>> ProcessQueryValue<'tcx, &'tcx [T]>
for Option<DecodeIterator<T, D>>
{
#[inline(always)]
fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx [T] {
@@ -74,8 +75,8 @@ fn process_decoded(self, tcx: TyCtxt<'tcx>, err: impl Fn() -> !) -> &'tcx [T] {
}
}
impl<'a, 'tcx, T: Copy + Decodable<DecodeContext<'a, 'tcx>>>
ProcessQueryValue<'tcx, Option<&'tcx [T]>> for Option<DecodeIterator<'a, 'tcx, T>>
impl<'tcx, D: Decoder, T: Copy + Decodable<D>> ProcessQueryValue<'tcx, Option<&'tcx [T]>>
for Option<DecodeIterator<T, D>>
{
#[inline(always)]
fn process_decoded(self, tcx: TyCtxt<'tcx>, _err: impl Fn() -> !) -> Option<&'tcx [T]> {
@@ -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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
.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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
.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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
.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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
.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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
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 @@ fn into_args(self) -> (DefId, SimplifiedType) {
}
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 @@ pub fn num_def_ids_untracked(&self, cnum: CrateNum) -> usize {
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);
}
};
}
@@ -3,7 +3,8 @@
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::def_id::{DefIndex, DefPathHash};
use crate::rmeta::{DecodeContext, EncodeContext};
use crate::rmeta::EncodeContext;
use crate::rmeta::decoder::BlobDecodeContext;
pub(crate) enum DefPathHashMapRef<'tcx> {
OwnedFromMetadata(odht::HashTable<HashMapConfig, OwnedSlice>),
@@ -40,8 +41,8 @@ fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) {
}
}
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefPathHashMapRef<'static> {
fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefPathHashMapRef<'static> {
impl<'a> Decodable<BlobDecodeContext<'a>> for DefPathHashMapRef<'static> {
fn decode(d: &mut BlobDecodeContext<'a>) -> DefPathHashMapRef<'static> {
let len = d.read_usize();
let pos = d.position();
let o = d.blob().bytes().clone().slice(|blob| &blob[pos..pos + len]);
+1 -1
View File
@@ -2205,7 +2205,7 @@ fn encode_incoherent_impls(&mut self) -> LazyArray<IncoherentImpls> {
.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();
+10 -10
View File
@@ -1,8 +1,8 @@
use std::marker::PhantomData;
use std::num::NonZero;
use decoder::LazyDecoder;
pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob, TargetModifiers};
use decoder::{DecodeContext, Metadata};
use def_path_hash_map::DefPathHashMapRef;
use encoder::EncodeContext;
pub use encoder::{EncodedMetadata, encode_metadata, rendered_const};
@@ -19,7 +19,7 @@
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 @@ enum LazyState {
type ExpnDataTable = LazyTable<ExpnIndex, Option<LazyValue<ExpnData>>>;
type ExpnHashTable = LazyTable<ExpnIndex, Option<LazyValue<ExpnHash>>>;
#[derive(MetadataEncodable, MetadataDecodable)]
#[derive(MetadataEncodable, LazyDecodable)]
pub(crate) struct ProcMacroData {
proc_macro_decls_static: DefIndex,
stability: Option<hir::Stability>,
@@ -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 @@ fn decode_from_cdata(self, cdata: CrateMetadataRef<'_>) -> DefId {
}
}
#[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<SimplifiedType>)>,
}
#[derive(MetadataEncodable, MetadataDecodable)]
#[derive(MetadataEncodable, LazyDecodable)]
pub(crate) struct IncoherentImpls {
self_ty: SimplifiedType,
self_ty: LazyValue<SimplifiedType>,
impls: LazyArray<DefIndex>,
}
@@ -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>>,)+
+2 -1
View File
@@ -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 @@ fn trailing_zeros(x: &[u8]) -> usize {
for<'tcx> T::Value<'tcx>: FixedSizeEncoding<ByteArray = [u8; N]>,
{
/// Given the metadata, extract out the value at a particular index (if any).
pub(super) fn get<'a, 'tcx, M: Metadata<'a, 'tcx>>(&self, metadata: M, i: I) -> T::Value<'tcx> {
pub(super) fn get<'a, 'tcx, M: 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();
+2 -2
View File
@@ -6,11 +6,11 @@
pub mod lang_items;
pub mod lib_features {
use rustc_data_structures::unord::UnordMap;
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_macros::{BlobDecodable, Encodable, HashStable};
use rustc_span::{Span, Symbol};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[derive(HashStable, TyEncodable, TyDecodable)]
#[derive(HashStable, Encodable, BlobDecodable)]
pub enum FeatureStability {
AcceptedSince(Symbol),
Unstable { old_name: Option<Symbol> },
@@ -20,8 +20,8 @@
};
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 @@ fn decode_span(&mut self) -> Span {
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 @@ fn decode_attr_id(&mut self) -> rustc_span::AttrId {
}
}
impl<'a, 'tcx> BlobDecoder for CacheDecoder<'a, 'tcx> {
fn decode_symbol(&mut self) -> Symbol {
self.decode_symbol_or_byte_symbol(
Symbol::new,
|this| Symbol::intern(this.read_str()),
|opaque| Symbol::intern(opaque.read_str()),
)
}
fn decode_byte_symbol(&mut self) -> ByteSymbol {
self.decode_symbol_or_byte_symbol(
ByteSymbol::new,
|this| ByteSymbol::intern(this.read_byte_str()),
|opaque| ByteSymbol::intern(opaque.read_byte_str()),
)
}
// This impl makes sure that we get a runtime error when we try decode a
// `DefIndex` that is not contained in a `DefId`. Such a case would be problematic
// because we would not know how to transform the `DefIndex` to the current
// context.
fn decode_def_index(&mut self) -> DefIndex {
panic!("trying to decode `DefIndex` outside the context of a `DefId`")
}
}
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx UnordSet<LocalDefId> {
#[inline]
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
+3 -3
View File
@@ -41,8 +41,8 @@
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 @@ pub fn is_async(self) -> bool {
}
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)]
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, BlobDecodable, HashStable)]
pub enum Visibility<Id = LocalDefId> {
/// Visible everywhere (including in other crates).
Public,
@@ -141,7 +141,7 @@ pub(crate) fn get_module(&self, def_id: DefId) -> Option<Module<'ra>> {
}
// 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 @@ pub(crate) fn get_module(&self, def_id: DefId) -> Option<Module<'ra>> {
.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 @@ pub(crate) fn get_macro_by_def_id(&self, def_id: DefId) -> &'ra MacroData {
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 @@ pub(crate) fn get_macro_by_def_id(&self, def_id: DefId) -> &'ra MacroData {
/// 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;
+1 -1
View File
@@ -1235,7 +1235,7 @@ fn finalize_module_binding(
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),
@@ -2024,7 +2024,7 @@ fn smart_resolve_context_dependent_help(
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);
+1 -1
View File
@@ -2316,7 +2316,7 @@ fn def_span(&self, def_id: DefId) -> Span {
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),
}
}
+1 -1
View File
@@ -477,7 +477,7 @@ fn macro_accessible(
}
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) {
+3 -3
View File
@@ -21,7 +21,7 @@
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 @@ pub fn enabled(&self) -> bool {
}
#[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,
+3 -3
View File
@@ -12,7 +12,7 @@
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 @@ pub fn paths(&self) -> impl Iterator<Item = &PathBuf> {
}
}
#[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 @@ pub fn macros_only(self) -> bool {
}
}
#[derive(Copy, Debug, PartialEq, Clone, Encodable, Decodable, HashStable_Generic)]
#[derive(Copy, Debug, PartialEq, Clone, Encodable, BlobDecodable, HashStable_Generic)]
pub enum LinkagePreference {
RequireDynamic,
RequireStatic,
+4 -4
View File
@@ -10,7 +10,7 @@
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),*
}
+2 -2
View File
@@ -7,7 +7,7 @@
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 {
+2 -2
View File
@@ -1,10 +1,10 @@
use std::fmt;
use std::str::FromStr;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_macros::{BlobDecodable, Encodable, HashStable_Generic};
/// The edition of the compiler. (See [RFC 2052](https://github.com/rust-lang/rfcs/blob/master/text/2052-epochs.md).)
#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, Decodable, Eq)]
#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Debug, Encodable, BlobDecodable, Eq)]
#[derive(HashStable_Generic)]
pub enum Edition {
// When adding new editions, be sure to do the following:
+39 -20
View File
@@ -1296,20 +1296,51 @@ fn encode(&self, _s: &mut E) {
}
}
/// This trait is used to allow decoder specific encodings of certain types.
/// It is similar to rustc_type_ir's TyDecoder.
pub trait SpanDecoder: Decoder {
fn decode_span(&mut self) -> Span;
pub trait BlobDecoder: Decoder {
fn decode_symbol(&mut self) -> Symbol;
fn decode_byte_symbol(&mut self) -> ByteSymbol;
fn decode_def_index(&mut self) -> DefIndex;
}
/// This trait is used to allow decoder specific encodings of certain types.
/// It is similar to rustc_type_ir's TyDecoder.
///
/// 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_expn_id(&mut self) -> ExpnId;
fn decode_syntax_context(&mut self) -> SyntaxContext;
fn decode_crate_num(&mut self) -> CrateNum;
fn decode_def_index(&mut self) -> DefIndex;
fn decode_def_id(&mut self) -> DefId;
fn decode_attr_id(&mut self) -> AttrId;
}
impl BlobDecoder for MemDecoder<'_> {
fn decode_symbol(&mut self) -> Symbol {
Symbol::intern(self.read_str())
}
fn decode_byte_symbol(&mut self) -> ByteSymbol {
ByteSymbol::intern(self.read_byte_str())
}
fn decode_def_index(&mut self) -> DefIndex {
panic!("cannot decode `DefIndex` with `MemDecoder`");
}
}
impl SpanDecoder for MemDecoder<'_> {
fn decode_span(&mut self) -> Span {
let lo = Decodable::decode(self);
@@ -1318,14 +1349,6 @@ fn decode_span(&mut self) -> Span {
Span::new(lo, hi, SyntaxContext::root(), None)
}
fn decode_symbol(&mut self) -> Symbol {
Symbol::intern(self.read_str())
}
fn decode_byte_symbol(&mut self) -> ByteSymbol {
ByteSymbol::intern(self.read_byte_str())
}
fn decode_expn_id(&mut self) -> ExpnId {
panic!("cannot decode `ExpnId` with `MemDecoder`");
}
@@ -1338,10 +1361,6 @@ fn decode_crate_num(&mut self) -> CrateNum {
CrateNum::from_u32(self.read_u32())
}
fn decode_def_index(&mut self) -> DefIndex {
panic!("cannot decode `DefIndex` with `MemDecoder`");
}
fn decode_def_id(&mut self) -> DefId {
DefId { krate: Decodable::decode(self), index: Decodable::decode(self) }
}
@@ -1357,13 +1376,13 @@ fn decode(s: &mut D) -> Span {
}
}
impl<D: SpanDecoder> Decodable<D> for Symbol {
impl<D: BlobDecoder> Decodable<D> for Symbol {
fn decode(s: &mut D) -> Symbol {
s.decode_symbol()
}
}
impl<D: SpanDecoder> Decodable<D> for ByteSymbol {
impl<D: BlobDecoder> Decodable<D> for ByteSymbol {
fn decode(s: &mut D) -> ByteSymbol {
s.decode_byte_symbol()
}
@@ -1387,7 +1406,7 @@ fn decode(s: &mut D) -> CrateNum {
}
}
impl<D: SpanDecoder> Decodable<D> for DefIndex {
impl<D: BlobDecoder> Decodable<D> for DefIndex {
fn decode(s: &mut D) -> DefIndex {
s.decode_def_index()
}
+3 -3
View File
@@ -52,7 +52,7 @@
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 @@ pub fn is_cc_enabled(self) -> bool {
}
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 @@ pub enum PanicStrategy {
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,
+2 -2
View File
@@ -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 <https://rust-lang.github.io/rfcs/1584-macros.html>.
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 {