1 use crate::creader
::CrateMetadataRef
;
3 use def_path_hash_map
::DefPathHashMapRef
;
4 use rustc_data_structures
::fx
::FxHashMap
;
5 use table
::TableBuilder
;
8 use rustc_attr
as attr
;
9 use rustc_data_structures
::svh
::Svh
;
10 use rustc_data_structures
::sync
::MetadataRef
;
12 use rustc_hir
::def
::{CtorKind, DefKind}
;
13 use rustc_hir
::def_id
::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId}
;
14 use rustc_hir
::definitions
::DefKey
;
15 use rustc_hir
::lang_items
::LangItem
;
16 use rustc_index
::bit_set
::BitSet
;
17 use rustc_index
::vec
::IndexVec
;
18 use rustc_middle
::metadata
::ModChild
;
19 use rustc_middle
::middle
::codegen_fn_attrs
::CodegenFnAttrs
;
20 use rustc_middle
::middle
::exported_symbols
::{ExportedSymbol, SymbolExportInfo}
;
21 use rustc_middle
::middle
::resolve_lifetime
::ObjectLifetimeDefault
;
22 use rustc_middle
::mir
;
23 use rustc_middle
::ty
::fast_reject
::SimplifiedType
;
24 use rustc_middle
::ty
::query
::Providers
;
25 use rustc_middle
::ty
::{self, ReprOptions, Ty, UnusedGenericParams}
;
26 use rustc_middle
::ty
::{DeducedParamAttrs, GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt}
;
27 use rustc_serialize
::opaque
::FileEncoder
;
28 use rustc_session
::config
::SymbolManglingVersion
;
29 use rustc_session
::cstore
::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}
;
30 use rustc_span
::edition
::Edition
;
31 use rustc_span
::hygiene
::{ExpnIndex, MacroKind}
;
32 use rustc_span
::symbol
::{Ident, Symbol}
;
33 use rustc_span
::{self, ExpnData, ExpnHash, ExpnId, Span}
;
34 use rustc_target
::spec
::{PanicStrategy, TargetTriple}
;
36 use std
::marker
::PhantomData
;
37 use std
::num
::NonZeroUsize
;
39 pub use decoder
::provide_extern
;
40 use decoder
::DecodeContext
;
41 pub(crate) use decoder
::{CrateMetadata, CrateNumMap, MetadataBlob}
;
42 use encoder
::EncodeContext
;
43 pub use encoder
::{encode_metadata, EncodedMetadata}
;
44 use rustc_span
::hygiene
::SyntaxContextData
;
47 mod def_path_hash_map
;
51 pub(crate) fn rustc_version() -> String
{
52 format
!("rustc {}", option_env
!("CFG_VERSION").unwrap_or("unknown version"))
55 /// Metadata encoding version.
56 /// N.B., increment this if you change the format of metadata such that
57 /// the rustc version can't be found to compare with `rustc_version()`.
58 const METADATA_VERSION
: u8 = 6;
60 /// Metadata header which includes `METADATA_VERSION`.
62 /// This header is followed by the position of the `CrateRoot`,
63 /// which is encoded as a 32-bit big-endian unsigned integer,
64 /// and further followed by the rustc version string.
65 pub const METADATA_HEADER
: &[u8] = &[b'r'
, b'u'
, b's'
, b't'
, 0, 0, 0, METADATA_VERSION
];
67 /// A value of type T referred to by its absolute position
68 /// in the metadata, and which can be decoded lazily.
70 /// Metadata is effective a tree, encoded in post-order,
71 /// and with the root's position written next to the header.
72 /// That means every single `LazyValue` points to some previous
73 /// location in the metadata and is part of a larger node.
75 /// The first `LazyValue` in a node is encoded as the backwards
76 /// distance from the position where the containing node
77 /// starts and where the `LazyValue` points to, while the rest
78 /// use the forward distance from the previous `LazyValue`.
79 /// Distances start at 1, as 0-byte nodes are invalid.
80 /// Also invalid are nodes being referred in a different
81 /// order than they were encoded in.
84 position
: NonZeroUsize
,
85 _marker
: PhantomData
<fn() -> T
>,
88 impl<T
: ParameterizedOverTcx
> ParameterizedOverTcx
for LazyValue
<T
> {
89 type Value
<'tcx
> = LazyValue
<T
::Value
<'tcx
>>;
92 impl<T
> LazyValue
<T
> {
93 fn from_position(position
: NonZeroUsize
) -> LazyValue
<T
> {
94 LazyValue { position, _marker: PhantomData }
98 /// A list of lazily-decoded values.
100 /// Unlike `LazyValue<Vec<T>>`, the length is encoded next to the
101 /// position, not at the position, which means that the length
102 /// doesn't need to be known before encoding all the elements.
104 /// If the length is 0, no position is encoded, but otherwise,
105 /// the encoding is that of `LazyArray`, with the distinction that
106 /// the minimal distance the length of the sequence, i.e.
107 /// it's assumed there's no 0-byte element in the sequence.
108 struct LazyArray
<T
> {
109 position
: NonZeroUsize
,
111 _marker
: PhantomData
<fn() -> T
>,
114 impl<T
: ParameterizedOverTcx
> ParameterizedOverTcx
for LazyArray
<T
> {
115 type Value
<'tcx
> = LazyArray
<T
::Value
<'tcx
>>;
118 impl<T
> LazyArray
<T
> {
119 fn from_position_and_num_elems(position
: NonZeroUsize
, num_elems
: usize) -> LazyArray
<T
> {
120 LazyArray { position, num_elems, _marker: PhantomData }
123 fn empty() -> LazyArray
<T
> {
124 LazyArray
::from_position_and_num_elems(NonZeroUsize
::new(1).unwrap(), 0)
128 /// A list of lazily-decoded values, with the added capability of random access.
130 /// Random-access table (i.e. offering constant-time `get`/`set`), similar to
131 /// `LazyArray<T>`, but without requiring encoding or decoding all the values
132 /// eagerly and in-order.
133 struct LazyTable
<I
, T
> {
134 position
: NonZeroUsize
,
136 _marker
: PhantomData
<fn(I
) -> T
>,
139 impl<I
: '
static, T
: ParameterizedOverTcx
> ParameterizedOverTcx
for LazyTable
<I
, T
> {
140 type Value
<'tcx
> = LazyTable
<I
, T
::Value
<'tcx
>>;
143 impl<I
, T
> LazyTable
<I
, T
> {
144 fn from_position_and_encoded_size(
145 position
: NonZeroUsize
,
147 ) -> LazyTable
<I
, T
> {
148 LazyTable { position, encoded_size, _marker: PhantomData }
152 impl<T
> Copy
for LazyValue
<T
> {}
153 impl<T
> Clone
for LazyValue
<T
> {
154 fn clone(&self) -> Self {
159 impl<T
> Copy
for LazyArray
<T
> {}
160 impl<T
> Clone
for LazyArray
<T
> {
161 fn clone(&self) -> Self {
166 impl<I
, T
> Copy
for LazyTable
<I
, T
> {}
167 impl<I
, T
> Clone
for LazyTable
<I
, T
> {
168 fn clone(&self) -> Self {
173 /// Encoding / decoding state for `Lazy`s (`LazyValue`, `LazyArray`, and `LazyTable`).
174 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
176 /// Outside of a metadata node.
179 /// Inside a metadata node, and before any `Lazy`s.
180 /// The position is that of the node itself.
181 NodeStart(NonZeroUsize
),
183 /// Inside a metadata node, with a previous `Lazy`s.
184 /// The position is where that previous `Lazy` would start.
185 Previous(NonZeroUsize
),
188 type SyntaxContextTable
= LazyTable
<u32, LazyValue
<SyntaxContextData
>>;
189 type ExpnDataTable
= LazyTable
<ExpnIndex
, LazyValue
<ExpnData
>>;
190 type ExpnHashTable
= LazyTable
<ExpnIndex
, LazyValue
<ExpnHash
>>;
192 #[derive(MetadataEncodable, MetadataDecodable)]
193 pub(crate) struct ProcMacroData
{
194 proc_macro_decls_static
: DefIndex
,
195 stability
: Option
<attr
::Stability
>,
196 macros
: LazyArray
<DefIndex
>,
199 /// Serialized metadata for a crate.
200 /// When compiling a proc-macro crate, we encode many of
201 /// the `LazyArray<T>` fields as `Lazy::empty()`. This serves two purposes:
203 /// 1. We avoid performing unnecessary work. Proc-macro crates can only
204 /// export proc-macros functions, which are compiled into a shared library.
205 /// As a result, a large amount of the information we normally store
206 /// (e.g. optimized MIR) is unneeded by downstream crates.
207 /// 2. We avoid serializing invalid `CrateNum`s. When we deserialize
208 /// a proc-macro crate, we don't load any of its dependencies (since we
209 /// just need to invoke a native function from the shared library).
210 /// This means that any foreign `CrateNum`s that we serialize cannot be
211 /// deserialized, since we will not know how to map them into the current
212 /// compilation session. If we were to serialize a proc-macro crate like
213 /// a normal crate, much of what we serialized would be unusable in addition
215 #[derive(MetadataEncodable, MetadataDecodable)]
216 pub(crate) struct CrateRoot
{
218 triple
: TargetTriple
,
219 extra_filename
: String
,
221 stable_crate_id
: StableCrateId
,
222 required_panic_strategy
: Option
<PanicStrategy
>,
223 panic_in_drop_strategy
: PanicStrategy
,
225 has_global_allocator
: bool
,
226 has_alloc_error_handler
: bool
,
227 has_panic_handler
: bool
,
228 has_default_lib_allocator
: bool
,
230 crate_deps
: LazyArray
<CrateDep
>,
231 dylib_dependency_formats
: LazyArray
<Option
<LinkagePreference
>>,
232 lib_features
: LazyArray
<(Symbol
, Option
<Symbol
>)>,
233 stability_implications
: LazyArray
<(Symbol
, Symbol
)>,
234 lang_items
: LazyArray
<(DefIndex
, LangItem
)>,
235 lang_items_missing
: LazyArray
<LangItem
>,
236 diagnostic_items
: LazyArray
<(Symbol
, DefIndex
)>,
237 native_libraries
: LazyArray
<NativeLib
>,
238 foreign_modules
: LazyArray
<ForeignModule
>,
239 traits
: LazyArray
<DefIndex
>,
240 impls
: LazyArray
<TraitImpls
>,
241 incoherent_impls
: LazyArray
<IncoherentImpls
>,
242 interpret_alloc_index
: LazyArray
<u32>,
243 proc_macro_data
: Option
<ProcMacroData
>,
246 debugger_visualizers
: LazyArray
<rustc_span
::DebuggerVisualizerFile
>,
248 exported_symbols
: LazyArray
<(ExportedSymbol
<'
static>, SymbolExportInfo
)>,
250 syntax_contexts
: SyntaxContextTable
,
251 expn_data
: ExpnDataTable
,
252 expn_hashes
: ExpnHashTable
,
254 def_path_hash_map
: LazyValue
<DefPathHashMapRef
<'
static>>,
256 source_map
: LazyTable
<u32, LazyValue
<rustc_span
::SourceFile
>>,
258 compiler_builtins
: bool
,
259 needs_allocator
: bool
,
260 needs_panic_runtime
: bool
,
263 profiler_runtime
: bool
,
264 symbol_mangling_version
: SymbolManglingVersion
,
267 /// On-disk representation of `DefId`.
268 /// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk
269 /// representation and the compilation session.
270 #[derive(Copy, Clone)]
271 pub(crate) struct RawDefId
{
276 impl Into
<RawDefId
> for DefId
{
277 fn into(self) -> RawDefId
{
278 RawDefId { krate: self.krate.as_u32(), index: self.index.as_u32() }
283 /// This exists so that `provide_one!` is happy
284 fn decode(self, meta
: (CrateMetadataRef
<'_
>, TyCtxt
<'_
>)) -> DefId
{
285 self.decode_from_cdata(meta
.0)
288 fn decode_from_cdata(self, cdata
: CrateMetadataRef
<'_
>) -> DefId
{
289 let krate
= CrateNum
::from_u32(self.krate
);
290 let krate
= cdata
.map_encoded_cnum_to_current(krate
);
291 DefId { krate, index: DefIndex::from_u32(self.index) }
295 #[derive(Encodable, Decodable)]
296 pub(crate) struct CrateDep
{
299 pub host_hash
: Option
<Svh
>,
300 pub kind
: CrateDepKind
,
301 pub extra_filename
: String
,
304 #[derive(MetadataEncodable, MetadataDecodable)]
305 pub(crate) struct TraitImpls
{
306 trait_id
: (u32, DefIndex
),
307 impls
: LazyArray
<(DefIndex
, Option
<SimplifiedType
>)>,
310 #[derive(MetadataEncodable, MetadataDecodable)]
311 pub(crate) struct IncoherentImpls
{
312 self_ty
: SimplifiedType
,
313 impls
: LazyArray
<DefIndex
>,
316 /// Define `LazyTables` and `TableBuilders` at the same time.
317 macro_rules
! define_tables
{
318 ($
($name
:ident
: Table
<$IDX
:ty
, $T
:ty
>),+ $
(,)?
) => {
319 #[derive(MetadataEncodable, MetadataDecodable)]
320 pub(crate) struct LazyTables
{
321 $
($name
: LazyTable
<$IDX
, $T
>),+
325 struct TableBuilders
{
326 $
($name
: TableBuilder
<$IDX
, $T
>),+
330 fn encode(&self, buf
: &mut FileEncoder
) -> LazyTables
{
332 $
($name
: self.$name
.encode(buf
)),+
340 attributes
: Table
<DefIndex
, LazyArray
<ast
::Attribute
>>,
341 children
: Table
<DefIndex
, LazyArray
<DefIndex
>>,
343 opt_def_kind
: Table
<DefIndex
, DefKind
>,
344 visibility
: Table
<DefIndex
, LazyValue
<ty
::Visibility
<DefIndex
>>>,
345 def_span
: Table
<DefIndex
, LazyValue
<Span
>>,
346 def_ident_span
: Table
<DefIndex
, LazyValue
<Span
>>,
347 lookup_stability
: Table
<DefIndex
, LazyValue
<attr
::Stability
>>,
348 lookup_const_stability
: Table
<DefIndex
, LazyValue
<attr
::ConstStability
>>,
349 lookup_default_body_stability
: Table
<DefIndex
, LazyValue
<attr
::DefaultBodyStability
>>,
350 lookup_deprecation_entry
: Table
<DefIndex
, LazyValue
<attr
::Deprecation
>>,
351 // As an optimization, a missing entry indicates an empty `&[]`.
352 explicit_item_bounds
: Table
<DefIndex
, LazyArray
<(ty
::Predicate
<'
static>, Span
)>>,
353 explicit_predicates_of
: Table
<DefIndex
, LazyValue
<ty
::GenericPredicates
<'
static>>>,
354 generics_of
: Table
<DefIndex
, LazyValue
<ty
::Generics
>>,
355 // As an optimization, a missing entry indicates an empty `&[]`.
356 inferred_outlives_of
: Table
<DefIndex
, LazyArray
<(ty
::Clause
<'
static>, Span
)>>,
357 super_predicates_of
: Table
<DefIndex
, LazyValue
<ty
::GenericPredicates
<'
static>>>,
358 type_of
: Table
<DefIndex
, LazyValue
<Ty
<'
static>>>,
359 variances_of
: Table
<DefIndex
, LazyArray
<ty
::Variance
>>,
360 fn_sig
: Table
<DefIndex
, LazyValue
<ty
::PolyFnSig
<'
static>>>,
361 codegen_fn_attrs
: Table
<DefIndex
, LazyValue
<CodegenFnAttrs
>>,
362 impl_trait_ref
: Table
<DefIndex
, LazyValue
<ty
::EarlyBinder
<ty
::TraitRef
<'
static>>>>,
363 const_param_default
: Table
<DefIndex
, LazyValue
<ty
::EarlyBinder
<rustc_middle
::ty
::Const
<'
static>>>>,
364 object_lifetime_default
: Table
<DefIndex
, LazyValue
<ObjectLifetimeDefault
>>,
365 optimized_mir
: Table
<DefIndex
, LazyValue
<mir
::Body
<'
static>>>,
366 mir_for_ctfe
: Table
<DefIndex
, LazyValue
<mir
::Body
<'
static>>>,
367 promoted_mir
: Table
<DefIndex
, LazyValue
<IndexVec
<mir
::Promoted
, mir
::Body
<'
static>>>>,
368 // FIXME(compiler-errors): Why isn't this a LazyArray?
369 thir_abstract_const
: Table
<DefIndex
, LazyValue
<ty
::Const
<'
static>>>,
370 impl_parent
: Table
<DefIndex
, RawDefId
>,
371 impl_polarity
: Table
<DefIndex
, ty
::ImplPolarity
>,
372 constness
: Table
<DefIndex
, hir
::Constness
>,
373 is_intrinsic
: Table
<DefIndex
, ()>,
374 impl_defaultness
: Table
<DefIndex
, hir
::Defaultness
>,
375 // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
376 coerce_unsized_info
: Table
<DefIndex
, LazyValue
<ty
::adjustment
::CoerceUnsizedInfo
>>,
377 mir_const_qualif
: Table
<DefIndex
, LazyValue
<mir
::ConstQualifs
>>,
378 rendered_const
: Table
<DefIndex
, LazyValue
<String
>>,
379 asyncness
: Table
<DefIndex
, hir
::IsAsync
>,
380 fn_arg_names
: Table
<DefIndex
, LazyArray
<Ident
>>,
381 generator_kind
: Table
<DefIndex
, LazyValue
<hir
::GeneratorKind
>>,
382 trait_def
: Table
<DefIndex
, LazyValue
<ty
::TraitDef
>>,
384 trait_item_def_id
: Table
<DefIndex
, RawDefId
>,
385 inherent_impls
: Table
<DefIndex
, LazyArray
<DefIndex
>>,
386 expn_that_defined
: Table
<DefIndex
, LazyValue
<ExpnId
>>,
387 unused_generic_params
: Table
<DefIndex
, LazyValue
<UnusedGenericParams
>>,
388 params_in_repr
: Table
<DefIndex
, LazyValue
<BitSet
<u32>>>,
389 repr_options
: Table
<DefIndex
, LazyValue
<ReprOptions
>>,
390 // `def_keys` and `def_path_hashes` represent a lazy version of a
391 // `DefPathTable`. This allows us to avoid deserializing an entire
392 // `DefPathTable` up front, since we may only ever use a few
393 // definitions from any given crate.
394 def_keys
: Table
<DefIndex
, LazyValue
<DefKey
>>,
395 def_path_hashes
: Table
<DefIndex
, DefPathHash
>,
396 proc_macro_quoted_spans
: Table
<usize, LazyValue
<Span
>>,
397 generator_diagnostic_data
: Table
<DefIndex
, LazyValue
<GeneratorDiagnosticData
<'
static>>>,
398 may_have_doc_links
: Table
<DefIndex
, ()>,
399 variant_data
: Table
<DefIndex
, LazyValue
<VariantData
>>,
400 assoc_container
: Table
<DefIndex
, ty
::AssocItemContainer
>,
401 // Slot is full when macro is macro_rules.
402 macro_rules
: Table
<DefIndex
, ()>,
403 macro_definition
: Table
<DefIndex
, LazyValue
<ast
::DelimArgs
>>,
404 proc_macro
: Table
<DefIndex
, MacroKind
>,
405 module_reexports
: Table
<DefIndex
, LazyArray
<ModChild
>>,
406 deduced_param_attrs
: Table
<DefIndex
, LazyArray
<DeducedParamAttrs
>>,
407 // Slot is full when opaque is TAIT.
408 is_type_alias_impl_trait
: Table
<DefIndex
, ()>,
410 trait_impl_trait_tys
: Table
<DefIndex
, LazyValue
<FxHashMap
<DefId
, Ty
<'
static>>>>,
413 #[derive(TyEncodable, TyDecodable)]
415 discr
: ty
::VariantDiscr
,
416 /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
417 ctor
: Option
<(CtorKind
, DefIndex
)>,
418 is_non_exhaustive
: bool
,
421 // Tags used for encoding Spans:
422 const TAG_VALID_SPAN_LOCAL
: u8 = 0;
423 const TAG_VALID_SPAN_FOREIGN
: u8 = 1;
424 const TAG_PARTIAL_SPAN
: u8 = 2;
426 // Tags for encoding Symbol's
427 const SYMBOL_STR
: u8 = 0;
428 const SYMBOL_OFFSET
: u8 = 1;
429 const SYMBOL_PREINTERNED
: u8 = 2;
431 pub fn provide(providers
: &mut Providers
) {
432 encoder
::provide(providers
);
433 decoder
::provide(providers
);
436 trivially_parameterized_over_tcx
! {