use crate::creader::CrateMetadataRef;
use decoder::Metadata;
use def_path_hash_map::DefPathHashMapRef;
-use table::{Table, TableBuilder};
+use table::TableBuilder;
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_middle::thir;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::GeneratorDiagnosticData;
use rustc_middle::ty::{self, ReprOptions, Ty};
+use rustc_middle::ty::{GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
use rustc_serialize::opaque::Encoder;
use rustc_session::config::SymbolManglingVersion;
use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
pub use decoder::provide_extern;
use decoder::DecodeContext;
-crate use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
+pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
use encoder::EncodeContext;
pub use encoder::{encode_metadata, EncodedMetadata};
use rustc_span::hygiene::SyntaxContextData;
mod encoder;
mod table;
-crate fn rustc_version() -> String {
+pub(crate) fn rustc_version() -> String {
format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version"))
}
/// and further followed by the rustc version string.
pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
-/// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
-/// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
-trait LazyMeta {
- type Meta: Copy + 'static;
-}
-
-impl<T> LazyMeta for T {
- type Meta = ();
-}
-
-impl<T> LazyMeta for [T] {
- type Meta = usize;
-}
-
/// A value of type T referred to by its absolute position
/// in the metadata, and which can be decoded lazily.
///
/// Distances start at 1, as 0-byte nodes are invalid.
/// Also invalid are nodes being referred in a different
/// order than they were encoded in.
-///
-/// # Sequences (`Lazy<[T]>`)
+#[must_use]
+struct LazyValue<T> {
+ position: NonZeroUsize,
+ _marker: PhantomData<fn() -> T>,
+}
+
+impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyValue<T> {
+ type Value<'tcx> = LazyValue<T::Value<'tcx>>;
+}
+
+impl<T> LazyValue<T> {
+ fn from_position(position: NonZeroUsize) -> LazyValue<T> {
+ LazyValue { position, _marker: PhantomData }
+ }
+}
+
+/// A list of lazily-decoded values.
///
/// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
/// position, not at the position, which means that the length
/// the encoding is that of `Lazy`, with the distinction that
/// the minimal distance the length of the sequence, i.e.
/// it's assumed there's no 0-byte element in the sequence.
-#[must_use]
-// FIXME(#59875) the `Meta` parameter only exists to dodge
-// invariance wrt `T` (coming from the `meta: T::Meta` field).
-struct Lazy<T, Meta = <T as LazyMeta>::Meta>
-where
- T: ?Sized + LazyMeta<Meta = Meta>,
- Meta: 'static + Copy,
-{
+struct LazyArray<T> {
+ position: NonZeroUsize,
+ num_elems: usize,
+ _marker: PhantomData<fn() -> T>,
+}
+
+impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyArray<T> {
+ type Value<'tcx> = LazyArray<T::Value<'tcx>>;
+}
+
+impl<T> LazyArray<T> {
+ fn from_position_and_num_elems(position: NonZeroUsize, num_elems: usize) -> LazyArray<T> {
+ LazyArray { position, num_elems, _marker: PhantomData }
+ }
+
+ fn empty() -> LazyArray<T> {
+ LazyArray::from_position_and_num_elems(NonZeroUsize::new(1).unwrap(), 0)
+ }
+}
+
+/// A list of lazily-decoded values, with the added capability of random access.
+///
+/// Random-access table (i.e. offering constant-time `get`/`set`), similar to
+/// `LazyArray<T>`, but without requiring encoding or decoding all the values
+/// eagerly and in-order.
+struct LazyTable<I, T> {
position: NonZeroUsize,
- meta: Meta,
- _marker: PhantomData<T>,
+ encoded_size: usize,
+ _marker: PhantomData<fn(I) -> T>,
+}
+
+impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for LazyTable<I, T> {
+ type Value<'tcx> = LazyTable<I, T::Value<'tcx>>;
}
-impl<T: ?Sized + LazyMeta> Lazy<T> {
- fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy<T> {
- Lazy { position, meta, _marker: PhantomData }
+impl<I, T> LazyTable<I, T> {
+ fn from_position_and_encoded_size(
+ position: NonZeroUsize,
+ encoded_size: usize,
+ ) -> LazyTable<I, T> {
+ LazyTable { position, encoded_size, _marker: PhantomData }
}
}
-impl<T> Lazy<T> {
- fn from_position(position: NonZeroUsize) -> Lazy<T> {
- Lazy::from_position_and_meta(position, ())
+impl<T> Copy for LazyValue<T> {}
+impl<T> Clone for LazyValue<T> {
+ fn clone(&self) -> Self {
+ *self
}
}
-impl<T> Lazy<[T]> {
- fn empty() -> Lazy<[T]> {
- Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0)
+impl<T> Copy for LazyArray<T> {}
+impl<T> Clone for LazyArray<T> {
+ fn clone(&self) -> Self {
+ *self
}
}
-impl<T: ?Sized + LazyMeta> Copy for Lazy<T> {}
-impl<T: ?Sized + LazyMeta> Clone for Lazy<T> {
+impl<I, T> Copy for LazyTable<I, T> {}
+impl<I, T> Clone for LazyTable<I, T> {
fn clone(&self) -> Self {
*self
}
Previous(NonZeroUsize),
}
-// FIXME(#59875) `Lazy!(T)` replaces `Lazy<T>`, passing the `Meta` parameter
-// manually, instead of relying on the default, to get the correct variance.
-// Only needed when `T` itself contains a parameter (e.g. `'tcx`).
-macro_rules! Lazy {
- (Table<$I:ty, $T:ty>) => {Lazy<Table<$I, $T>, usize>};
- ([$T:ty]) => {Lazy<[$T], usize>};
- ($T:ty) => {Lazy<$T, ()>};
-}
-
-type SyntaxContextTable = Lazy<Table<u32, Lazy<SyntaxContextData>>>;
-type ExpnDataTable = Lazy<Table<ExpnIndex, Lazy<ExpnData>>>;
-type ExpnHashTable = Lazy<Table<ExpnIndex, Lazy<ExpnHash>>>;
+type SyntaxContextTable = LazyTable<u32, LazyValue<SyntaxContextData>>;
+type ExpnDataTable = LazyTable<ExpnIndex, LazyValue<ExpnData>>;
+type ExpnHashTable = LazyTable<ExpnIndex, LazyValue<ExpnHash>>;
#[derive(MetadataEncodable, MetadataDecodable)]
-crate struct ProcMacroData {
+pub(crate) struct ProcMacroData {
proc_macro_decls_static: DefIndex,
stability: Option<attr::Stability>,
- macros: Lazy<[DefIndex]>,
+ macros: LazyArray<DefIndex>,
}
/// Serialized metadata for a crate.
/// When compiling a proc-macro crate, we encode many of
-/// the `Lazy<[T]>` fields as `Lazy::empty()`. This serves two purposes:
+/// the `LazyArray<T>` fields as `Lazy::empty()`. This serves two purposes:
///
/// 1. We avoid performing unnecessary work. Proc-macro crates can only
/// export proc-macros functions, which are compiled into a shared library.
/// a normal crate, much of what we serialized would be unusable in addition
/// to being unused.
#[derive(MetadataEncodable, MetadataDecodable)]
-crate struct CrateRoot<'tcx> {
+pub(crate) struct CrateRoot {
name: Symbol,
triple: TargetTriple,
extra_filename: String,
has_panic_handler: bool,
has_default_lib_allocator: bool,
- crate_deps: Lazy<[CrateDep]>,
- dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
- lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
- lang_items: Lazy<[(DefIndex, usize)]>,
- lang_items_missing: Lazy<[lang_items::LangItem]>,
- diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
- native_libraries: Lazy<[NativeLib]>,
- foreign_modules: Lazy<[ForeignModule]>,
- traits: Lazy<[DefIndex]>,
- impls: Lazy<[TraitImpls]>,
- incoherent_impls: Lazy<[IncoherentImpls]>,
- interpret_alloc_index: Lazy<[u32]>,
+ crate_deps: LazyArray<CrateDep>,
+ dylib_dependency_formats: LazyArray<Option<LinkagePreference>>,
+ lib_features: LazyArray<(Symbol, Option<Symbol>)>,
+ lang_items: LazyArray<(DefIndex, usize)>,
+ lang_items_missing: LazyArray<lang_items::LangItem>,
+ diagnostic_items: LazyArray<(Symbol, DefIndex)>,
+ native_libraries: LazyArray<NativeLib>,
+ foreign_modules: LazyArray<ForeignModule>,
+ traits: LazyArray<DefIndex>,
+ impls: LazyArray<TraitImpls>,
+ incoherent_impls: LazyArray<IncoherentImpls>,
+ interpret_alloc_index: LazyArray<u32>,
proc_macro_data: Option<ProcMacroData>,
- tables: LazyTables<'tcx>,
- debugger_visualizers: Lazy<[rustc_span::DebuggerVisualizerFile]>,
+ tables: LazyTables,
+ debugger_visualizers: LazyArray<rustc_span::DebuggerVisualizerFile>,
- exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportInfo)]),
+ exported_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,
syntax_contexts: SyntaxContextTable,
expn_data: ExpnDataTable,
expn_hashes: ExpnHashTable,
- def_path_hash_map: Lazy<DefPathHashMapRef<'tcx>>,
+ def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,
- source_map: Lazy<[rustc_span::SourceFile]>,
+ source_map: LazyArray<rustc_span::SourceFile>,
compiler_builtins: bool,
needs_allocator: bool,
/// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk
/// representation and the compilation session.
#[derive(Copy, Clone)]
-crate struct RawDefId {
+pub(crate) struct RawDefId {
krate: u32,
index: u32,
}
}
impl RawDefId {
- fn decode(self, cdata: CrateMetadataRef<'_>) -> DefId {
+ /// This exists so that `provide_one!` is happy
+ fn decode(self, meta: (CrateMetadataRef<'_>, TyCtxt<'_>)) -> DefId {
+ self.decode_from_cdata(meta.0)
+ }
+
+ fn decode_from_cdata(self, cdata: CrateMetadataRef<'_>) -> DefId {
let krate = CrateNum::from_u32(self.krate);
let krate = cdata.map_encoded_cnum_to_current(krate);
DefId { krate, index: DefIndex::from_u32(self.index) }
}
#[derive(Encodable, Decodable)]
-crate struct CrateDep {
+pub(crate) struct CrateDep {
pub name: Symbol,
pub hash: Svh,
pub host_hash: Option<Svh>,
}
#[derive(MetadataEncodable, MetadataDecodable)]
-crate struct TraitImpls {
+pub(crate) struct TraitImpls {
trait_id: (u32, DefIndex),
- impls: Lazy<[(DefIndex, Option<SimplifiedType>)]>,
+ impls: LazyArray<(DefIndex, Option<SimplifiedType>)>,
}
#[derive(MetadataEncodable, MetadataDecodable)]
-crate struct IncoherentImpls {
+pub(crate) struct IncoherentImpls {
self_ty: SimplifiedType,
- impls: Lazy<[DefIndex]>,
+ impls: LazyArray<DefIndex>,
}
/// Define `LazyTables` and `TableBuilders` at the same time.
macro_rules! define_tables {
($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
#[derive(MetadataEncodable, MetadataDecodable)]
- crate struct LazyTables<'tcx> {
- $($name: Lazy!(Table<$IDX, $T>)),+
+ pub(crate) struct LazyTables {
+ $($name: LazyTable<$IDX, $T>),+
}
#[derive(Default)]
- struct TableBuilders<'tcx> {
+ struct TableBuilders {
$($name: TableBuilder<$IDX, $T>),+
}
- impl<'tcx> TableBuilders<'tcx> {
- fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
+ impl TableBuilders {
+ fn encode(&self, buf: &mut Encoder) -> LazyTables {
LazyTables {
$($name: self.$name.encode(buf)),+
}
}
define_tables! {
- kind: Table<DefIndex, Lazy<EntryKind>>,
- attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
- children: Table<DefIndex, Lazy<[DefIndex]>>,
+ kind: Table<DefIndex, LazyValue<EntryKind>>,
+ attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
+ children: Table<DefIndex, LazyArray<DefIndex>>,
opt_def_kind: Table<DefIndex, DefKind>,
- visibility: Table<DefIndex, Lazy<ty::Visibility>>,
- def_span: Table<DefIndex, Lazy<Span>>,
- def_ident_span: Table<DefIndex, Lazy<Span>>,
- lookup_stability: Table<DefIndex, Lazy<attr::Stability>>,
- lookup_const_stability: Table<DefIndex, Lazy<attr::ConstStability>>,
- lookup_deprecation_entry: Table<DefIndex, Lazy<attr::Deprecation>>,
+ visibility: Table<DefIndex, LazyValue<ty::Visibility>>,
+ def_span: Table<DefIndex, LazyValue<Span>>,
+ def_ident_span: Table<DefIndex, LazyValue<Span>>,
+ lookup_stability: Table<DefIndex, LazyValue<attr::Stability>>,
+ lookup_const_stability: Table<DefIndex, LazyValue<attr::ConstStability>>,
+ lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
// As an optimization, a missing entry indicates an empty `&[]`.
- explicit_item_bounds: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>,
- explicit_predicates_of: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
- generics_of: Table<DefIndex, Lazy<ty::Generics>>,
+ explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
+ explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
+ generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
// As an optimization, a missing entry indicates an empty `&[]`.
- inferred_outlives_of: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>,
- super_predicates_of: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
- type_of: Table<DefIndex, Lazy!(Ty<'tcx>)>,
- variances_of: Table<DefIndex, Lazy<[ty::Variance]>>,
- fn_sig: Table<DefIndex, Lazy!(ty::PolyFnSig<'tcx>)>,
- codegen_fn_attrs: Table<DefIndex, Lazy!(CodegenFnAttrs)>,
- impl_trait_ref: Table<DefIndex, Lazy!(ty::TraitRef<'tcx>)>,
- const_param_default: Table<DefIndex, Lazy<rustc_middle::ty::Const<'tcx>>>,
- optimized_mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
- mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
- promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
- thir_abstract_const: Table<DefIndex, Lazy!(&'tcx [thir::abstract_const::Node<'tcx>])>,
+ inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
+ super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
+ type_of: Table<DefIndex, LazyValue<Ty<'static>>>,
+ variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
+ fn_sig: Table<DefIndex, LazyValue<ty::PolyFnSig<'static>>>,
+ codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
+ impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'static>>>,
+ const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'static>>>,
+ optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
+ mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
+ promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
+ // FIXME(compiler-errors): Why isn't this a LazyArray?
+ thir_abstract_const: Table<DefIndex, LazyValue<&'static [thir::abstract_const::Node<'static>]>>,
impl_parent: Table<DefIndex, RawDefId>,
impl_polarity: Table<DefIndex, ty::ImplPolarity>,
impl_constness: Table<DefIndex, hir::Constness>,
is_intrinsic: Table<DefIndex, ()>,
impl_defaultness: Table<DefIndex, hir::Defaultness>,
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
- coerce_unsized_info: Table<DefIndex, Lazy!(ty::adjustment::CoerceUnsizedInfo)>,
- mir_const_qualif: Table<DefIndex, Lazy!(mir::ConstQualifs)>,
- rendered_const: Table<DefIndex, Lazy!(String)>,
+ coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
+ mir_const_qualif: Table<DefIndex, LazyValue<mir::ConstQualifs>>,
+ rendered_const: Table<DefIndex, LazyValue<String>>,
asyncness: Table<DefIndex, hir::IsAsync>,
- fn_arg_names: Table<DefIndex, Lazy!([Ident])>,
- generator_kind: Table<DefIndex, Lazy!(hir::GeneratorKind)>,
- trait_def: Table<DefIndex, Lazy!(ty::TraitDef)>,
+ fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
+ generator_kind: Table<DefIndex, LazyValue<hir::GeneratorKind>>,
+ trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
trait_item_def_id: Table<DefIndex, RawDefId>,
- inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
- expn_that_defined: Table<DefIndex, Lazy<ExpnId>>,
- unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
- repr_options: Table<DefIndex, Lazy<ReprOptions>>,
+ inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
+ expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
+ unused_generic_params: Table<DefIndex, LazyValue<FiniteBitSet<u32>>>,
+ repr_options: Table<DefIndex, LazyValue<ReprOptions>>,
// `def_keys` and `def_path_hashes` represent a lazy version of a
// `DefPathTable`. This allows us to avoid deserializing an entire
// `DefPathTable` up front, since we may only ever use a few
// definitions from any given crate.
- def_keys: Table<DefIndex, Lazy<DefKey>>,
+ def_keys: Table<DefIndex, LazyValue<DefKey>>,
def_path_hashes: Table<DefIndex, DefPathHash>,
- proc_macro_quoted_spans: Table<usize, Lazy<Span>>,
- generator_diagnostic_data: Table<DefIndex, Lazy<GeneratorDiagnosticData<'tcx>>>,
+ proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
+ generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
may_have_doc_links: Table<DefIndex, ()>,
}
OpaqueTy,
Enum,
Field,
- Variant(Lazy<VariantData>),
- Struct(Lazy<VariantData>),
- Union(Lazy<VariantData>),
+ Variant(LazyValue<VariantData>),
+ Struct(LazyValue<VariantData>),
+ Union(LazyValue<VariantData>),
Fn,
ForeignFn,
- Mod(Lazy<[ModChild]>),
- MacroDef(Lazy<ast::MacArgs>, /*macro_rules*/ bool),
+ Mod(LazyArray<ModChild>),
+ MacroDef(LazyValue<ast::MacArgs>, /*macro_rules*/ bool),
ProcMacro(MacroKind),
Closure,
Generator,
Trait,
Impl,
- AssocFn(Lazy<AssocFnData>),
+ AssocFn(LazyValue<AssocFnData>),
AssocType(AssocContainer),
AssocConst(AssocContainer),
TraitAlias,
encoder::provide(providers);
decoder::provide(providers);
}
+
+trivially_parameterized_over_tcx! {
+ VariantData,
+ AssocFnData,
+ EntryKind,
+ RawDefId,
+ TraitImpls,
+ IncoherentImpls,
+ CrateRoot,
+ CrateDep,
+}