2 use def_path_hash_map
::DefPathHashMapRef
;
3 use table
::{Table, TableBuilder}
;
5 use rustc_ast
::{self as ast, MacroDef}
;
6 use rustc_attr
as attr
;
7 use rustc_data_structures
::svh
::Svh
;
8 use rustc_data_structures
::sync
::MetadataRef
;
10 use rustc_hir
::def
::{CtorKind, DefKind}
;
11 use rustc_hir
::def_id
::{DefId, DefIndex, DefPathHash, StableCrateId}
;
12 use rustc_hir
::definitions
::DefKey
;
13 use rustc_hir
::lang_items
;
14 use rustc_index
::{bit_set::FiniteBitSet, vec::IndexVec}
;
15 use rustc_middle
::hir
::exports
::Export
;
16 use rustc_middle
::middle
::exported_symbols
::{ExportedSymbol, SymbolExportLevel}
;
17 use rustc_middle
::mir
;
18 use rustc_middle
::thir
;
19 use rustc_middle
::ty
::{self, ReprOptions, Ty}
;
20 use rustc_serialize
::opaque
::Encoder
;
21 use rustc_session
::config
::SymbolManglingVersion
;
22 use rustc_session
::cstore
::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}
;
23 use rustc_span
::edition
::Edition
;
24 use rustc_span
::hygiene
::{ExpnIndex, MacroKind}
;
25 use rustc_span
::symbol
::{Ident, Symbol}
;
26 use rustc_span
::{self, ExpnData, ExpnHash, ExpnId, Span}
;
27 use rustc_target
::spec
::{PanicStrategy, TargetTriple}
;
29 use std
::marker
::PhantomData
;
30 use std
::num
::NonZeroUsize
;
32 use decoder
::DecodeContext
;
33 pub use decoder
::{provide, provide_extern}
;
34 crate use decoder
::{CrateMetadata, CrateNumMap, MetadataBlob}
;
35 use encoder
::EncodeContext
;
36 pub use encoder
::{encode_metadata, EncodedMetadata}
;
37 use rustc_span
::hygiene
::SyntaxContextData
;
40 mod def_path_hash_map
;
44 crate fn rustc_version() -> String
{
45 format
!("rustc {}", option_env
!("CFG_VERSION").unwrap_or("unknown version"))
48 /// Metadata encoding version.
49 /// N.B., increment this if you change the format of metadata such that
50 /// the rustc version can't be found to compare with `rustc_version()`.
51 const METADATA_VERSION
: u8 = 5;
53 /// Metadata header which includes `METADATA_VERSION`.
55 /// This header is followed by the position of the `CrateRoot`,
56 /// which is encoded as a 32-bit big-endian unsigned integer,
57 /// and further followed by the rustc version string.
58 pub const METADATA_HEADER
: &[u8] = &[b'r'
, b'u'
, b's'
, b't'
, 0, 0, 0, METADATA_VERSION
];
60 /// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
61 /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
63 type Meta
: Copy
+ '
static;
65 /// Returns the minimum encoded size.
66 // FIXME(eddyb) Give better estimates for certain types.
67 fn min_size(meta
: Self::Meta
) -> usize;
70 impl<T
> LazyMeta
for T
{
73 fn min_size(_
: ()) -> usize {
74 assert_ne
!(std
::mem
::size_of
::<T
>(), 0);
79 impl<T
> LazyMeta
for [T
] {
82 fn min_size(len
: usize) -> usize {
87 /// A value of type T referred to by its absolute position
88 /// in the metadata, and which can be decoded lazily.
90 /// Metadata is effective a tree, encoded in post-order,
91 /// and with the root's position written next to the header.
92 /// That means every single `Lazy` points to some previous
93 /// location in the metadata and is part of a larger node.
95 /// The first `Lazy` in a node is encoded as the backwards
96 /// distance from the position where the containing node
97 /// starts and where the `Lazy` points to, while the rest
98 /// use the forward distance from the previous `Lazy`.
99 /// Distances start at 1, as 0-byte nodes are invalid.
100 /// Also invalid are nodes being referred in a different
101 /// order than they were encoded in.
103 /// # Sequences (`Lazy<[T]>`)
105 /// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
106 /// position, not at the position, which means that the length
107 /// doesn't need to be known before encoding all the elements.
109 /// If the length is 0, no position is encoded, but otherwise,
110 /// the encoding is that of `Lazy`, with the distinction that
111 /// the minimal distance the length of the sequence, i.e.
112 /// it's assumed there's no 0-byte element in the sequence.
114 // FIXME(#59875) the `Meta` parameter only exists to dodge
115 // invariance wrt `T` (coming from the `meta: T::Meta` field).
116 struct Lazy
<T
, Meta
= <T
as LazyMeta
>::Meta
>
118 T
: ?Sized
+ LazyMeta
<Meta
= Meta
>,
119 Meta
: '
static + Copy
,
121 position
: NonZeroUsize
,
123 _marker
: PhantomData
<T
>,
126 impl<T
: ?Sized
+ LazyMeta
> Lazy
<T
> {
127 fn from_position_and_meta(position
: NonZeroUsize
, meta
: T
::Meta
) -> Lazy
<T
> {
128 Lazy { position, meta, _marker: PhantomData }
133 fn from_position(position
: NonZeroUsize
) -> Lazy
<T
> {
134 Lazy
::from_position_and_meta(position
, ())
139 fn empty() -> Lazy
<[T
]> {
140 Lazy
::from_position_and_meta(NonZeroUsize
::new(1).unwrap(), 0)
144 impl<T
: ?Sized
+ LazyMeta
> Copy
for Lazy
<T
> {}
145 impl<T
: ?Sized
+ LazyMeta
> Clone
for Lazy
<T
> {
146 fn clone(&self) -> Self {
151 /// Encoding / decoding state for `Lazy`.
152 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
154 /// Outside of a metadata node.
157 /// Inside a metadata node, and before any `Lazy`.
158 /// The position is that of the node itself.
159 NodeStart(NonZeroUsize
),
161 /// Inside a metadata node, with a previous `Lazy`.
162 /// The position is a conservative estimate of where that
163 /// previous `Lazy` would end (see their comments).
164 Previous(NonZeroUsize
),
167 // FIXME(#59875) `Lazy!(T)` replaces `Lazy<T>`, passing the `Meta` parameter
168 // manually, instead of relying on the default, to get the correct variance.
169 // Only needed when `T` itself contains a parameter (e.g. `'tcx`).
171 (Table
<$I
:ty
, $T
:ty
>) => {Lazy<Table<$I, $T>, usize>}
;
172 ([$T
:ty
]) => {Lazy<[$T], usize>}
;
173 ($T
:ty
) => {Lazy<$T, ()>}
;
176 type SyntaxContextTable
= Lazy
<Table
<u32, Lazy
<SyntaxContextData
>>>;
177 type ExpnDataTable
= Lazy
<Table
<ExpnIndex
, Lazy
<ExpnData
>>>;
178 type ExpnHashTable
= Lazy
<Table
<ExpnIndex
, Lazy
<ExpnHash
>>>;
180 #[derive(MetadataEncodable, MetadataDecodable)]
181 crate struct ProcMacroData
{
182 proc_macro_decls_static
: DefIndex
,
183 stability
: Option
<attr
::Stability
>,
184 macros
: Lazy
<[DefIndex
]>,
187 /// Serialized metadata for a crate.
188 /// When compiling a proc-macro crate, we encode many of
189 /// the `Lazy<[T]>` fields as `Lazy::empty()`. This serves two purposes:
191 /// 1. We avoid performing unnecessary work. Proc-macro crates can only
192 /// export proc-macros functions, which are compiled into a shared library.
193 /// As a result, a large amount of the information we normally store
194 /// (e.g. optimized MIR) is unneeded by downstream crates.
195 /// 2. We avoid serializing invalid `CrateNum`s. When we deserialize
196 /// a proc-macro crate, we don't load any of its dependencies (since we
197 /// just need to invoke a native function from the shared library).
198 /// This means that any foreign `CrateNum`s that we serialize cannot be
199 /// deserialized, since we will not know how to map them into the current
200 /// compilation session. If we were to serialize a proc-macro crate like
201 /// a normal crate, much of what we serialized would be unusable in addition
203 #[derive(MetadataEncodable, MetadataDecodable)]
204 crate struct CrateRoot
<'tcx
> {
206 triple
: TargetTriple
,
207 extra_filename
: String
,
209 stable_crate_id
: StableCrateId
,
210 panic_strategy
: PanicStrategy
,
211 panic_in_drop_strategy
: PanicStrategy
,
213 has_global_allocator
: bool
,
214 has_panic_handler
: bool
,
215 has_default_lib_allocator
: bool
,
217 crate_deps
: Lazy
<[CrateDep
]>,
218 dylib_dependency_formats
: Lazy
<[Option
<LinkagePreference
>]>,
219 lib_features
: Lazy
<[(Symbol
, Option
<Symbol
>)]>,
220 lang_items
: Lazy
<[(DefIndex
, usize)]>,
221 lang_items_missing
: Lazy
<[lang_items
::LangItem
]>,
222 diagnostic_items
: Lazy
<[(Symbol
, DefIndex
)]>,
223 native_libraries
: Lazy
<[NativeLib
]>,
224 foreign_modules
: Lazy
<[ForeignModule
]>,
225 impls
: Lazy
<[TraitImpls
]>,
226 interpret_alloc_index
: Lazy
<[u32]>,
227 proc_macro_data
: Option
<ProcMacroData
>,
229 tables
: LazyTables
<'tcx
>,
231 exported_symbols
: Lazy
!([(ExportedSymbol
<'tcx
>, SymbolExportLevel
)]),
233 syntax_contexts
: SyntaxContextTable
,
234 expn_data
: ExpnDataTable
,
235 expn_hashes
: ExpnHashTable
,
237 def_path_hash_map
: Lazy
<DefPathHashMapRef
<'tcx
>>,
239 source_map
: Lazy
<[rustc_span
::SourceFile
]>,
241 compiler_builtins
: bool
,
242 needs_allocator
: bool
,
243 needs_panic_runtime
: bool
,
246 profiler_runtime
: bool
,
247 symbol_mangling_version
: SymbolManglingVersion
,
250 #[derive(Encodable, Decodable)]
251 crate struct CrateDep
{
254 pub host_hash
: Option
<Svh
>,
255 pub kind
: CrateDepKind
,
256 pub extra_filename
: String
,
259 #[derive(MetadataEncodable, MetadataDecodable)]
260 crate struct TraitImpls
{
261 trait_id
: (u32, DefIndex
),
262 impls
: Lazy
<[(DefIndex
, Option
<ty
::fast_reject
::SimplifiedType
>)]>,
265 /// Define `LazyTables` and `TableBuilders` at the same time.
266 macro_rules
! define_tables
{
267 ($
($name
:ident
: Table
<$IDX
:ty
, $T
:ty
>),+ $
(,)?
) => {
268 #[derive(MetadataEncodable, MetadataDecodable)]
269 crate struct LazyTables
<'tcx
> {
270 $
($name
: Lazy
!(Table
<$IDX
, $T
>)),+
274 struct TableBuilders
<'tcx
> {
275 $
($name
: TableBuilder
<$IDX
, $T
>),+
278 impl TableBuilders
<'tcx
> {
279 fn encode(&self, buf
: &mut Encoder
) -> LazyTables
<'tcx
> {
281 $
($name
: self.$name
.encode(buf
)),+
289 def_kind
: Table
<DefIndex
, Lazy
<DefKind
>>,
290 kind
: Table
<DefIndex
, Lazy
<EntryKind
>>,
291 visibility
: Table
<DefIndex
, Lazy
<ty
::Visibility
>>,
292 span
: Table
<DefIndex
, Lazy
<Span
>>,
293 ident_span
: Table
<DefIndex
, Lazy
<Span
>>,
294 attributes
: Table
<DefIndex
, Lazy
<[ast
::Attribute
]>>,
295 children
: Table
<DefIndex
, Lazy
<[DefIndex
]>>,
296 stability
: Table
<DefIndex
, Lazy
<attr
::Stability
>>,
297 const_stability
: Table
<DefIndex
, Lazy
<attr
::ConstStability
>>,
298 deprecation
: Table
<DefIndex
, Lazy
<attr
::Deprecation
>>,
299 ty
: Table
<DefIndex
, Lazy
!(Ty
<'tcx
>)>,
300 fn_sig
: Table
<DefIndex
, Lazy
!(ty
::PolyFnSig
<'tcx
>)>,
301 impl_trait_ref
: Table
<DefIndex
, Lazy
!(ty
::TraitRef
<'tcx
>)>,
302 inherent_impls
: Table
<DefIndex
, Lazy
<[DefIndex
]>>,
303 variances
: Table
<DefIndex
, Lazy
<[ty
::Variance
]>>,
304 generics
: Table
<DefIndex
, Lazy
<ty
::Generics
>>,
305 explicit_predicates
: Table
<DefIndex
, Lazy
!(ty
::GenericPredicates
<'tcx
>)>,
306 expn_that_defined
: Table
<DefIndex
, Lazy
<ExpnId
>>,
307 // As an optimization, a missing entry indicates an empty `&[]`.
308 inferred_outlives
: Table
<DefIndex
, Lazy
!([(ty
::Predicate
<'tcx
>, Span
)])>,
309 super_predicates
: Table
<DefIndex
, Lazy
!(ty
::GenericPredicates
<'tcx
>)>,
310 // As an optimization, a missing entry indicates an empty `&[]`.
311 explicit_item_bounds
: Table
<DefIndex
, Lazy
!([(ty
::Predicate
<'tcx
>, Span
)])>,
312 mir
: Table
<DefIndex
, Lazy
!(mir
::Body
<'tcx
>)>,
313 mir_for_ctfe
: Table
<DefIndex
, Lazy
!(mir
::Body
<'tcx
>)>,
314 promoted_mir
: Table
<DefIndex
, Lazy
!(IndexVec
<mir
::Promoted
, mir
::Body
<'tcx
>>)>,
315 thir_abstract_consts
: Table
<DefIndex
, Lazy
!(&'tcx
[thir
::abstract_const
::Node
<'tcx
>])>,
316 const_defaults
: Table
<DefIndex
, Lazy
<rustc_middle
::ty
::Const
<'tcx
>>>,
317 unused_generic_params
: Table
<DefIndex
, Lazy
<FiniteBitSet
<u32>>>,
318 // `def_keys` and `def_path_hashes` represent a lazy version of a
319 // `DefPathTable`. This allows us to avoid deserializing an entire
320 // `DefPathTable` up front, since we may only ever use a few
321 // definitions from any given crate.
322 def_keys
: Table
<DefIndex
, Lazy
<DefKey
>>,
323 def_path_hashes
: Table
<DefIndex
, Lazy
<DefPathHash
>>,
324 proc_macro_quoted_spans
: Table
<usize, Lazy
<Span
>>,
327 #[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
329 AnonConst(mir
::ConstQualifs
, Lazy
<RenderedConst
>),
330 Const(mir
::ConstQualifs
, Lazy
<RenderedConst
>),
344 Variant(Lazy
<VariantData
>),
345 Struct(Lazy
<VariantData
>, ReprOptions
),
346 Union(Lazy
<VariantData
>, ReprOptions
),
348 ForeignFn(Lazy
<FnData
>),
350 MacroDef(Lazy
<MacroDef
>),
351 ProcMacro(MacroKind
),
353 Generator(hir
::GeneratorKind
),
354 Trait(Lazy
<TraitData
>),
355 Impl(Lazy
<ImplData
>),
356 AssocFn(Lazy
<AssocFnData
>),
357 AssocType(AssocContainer
),
358 AssocConst(AssocContainer
, mir
::ConstQualifs
, Lazy
<RenderedConst
>),
362 /// Contains a constant which has been rendered to a String.
364 #[derive(Encodable, Decodable)]
365 struct RenderedConst(String
);
367 #[derive(MetadataEncodable, MetadataDecodable)]
369 reexports
: Lazy
<[Export
]>,
373 #[derive(MetadataEncodable, MetadataDecodable)]
375 asyncness
: hir
::IsAsync
,
376 constness
: hir
::Constness
,
377 param_names
: Lazy
<[Ident
]>,
380 #[derive(TyEncodable, TyDecodable)]
383 discr
: ty
::VariantDiscr
,
384 /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
385 ctor
: Option
<DefIndex
>,
386 is_non_exhaustive
: bool
,
389 #[derive(TyEncodable, TyDecodable)]
391 unsafety
: hir
::Unsafety
,
395 skip_array_during_method_dispatch
: bool
,
396 specialization_kind
: ty
::trait_def
::TraitSpecializationKind
,
399 #[derive(TyEncodable, TyDecodable)]
401 polarity
: ty
::ImplPolarity
,
402 constness
: hir
::Constness
,
403 defaultness
: hir
::Defaultness
,
404 parent_impl
: Option
<DefId
>,
406 /// This is `Some` only for impls of `CoerceUnsized`.
407 // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
408 coerce_unsized_info
: Option
<ty
::adjustment
::CoerceUnsizedInfo
>,
411 /// Describes whether the container of an associated item
412 /// is a trait or an impl and whether, in a trait, it has
413 /// a default, or an in impl, whether it's marked "default".
414 #[derive(Copy, Clone, TyEncodable, TyDecodable)]
415 enum AssocContainer
{
422 impl AssocContainer
{
423 fn with_def_id(&self, def_id
: DefId
) -> ty
::AssocItemContainer
{
425 AssocContainer
::TraitRequired
| AssocContainer
::TraitWithDefault
=> {
426 ty
::TraitContainer(def_id
)
429 AssocContainer
::ImplDefault
| AssocContainer
::ImplFinal
=> ty
::ImplContainer(def_id
),
433 fn defaultness(&self) -> hir
::Defaultness
{
435 AssocContainer
::TraitRequired
=> hir
::Defaultness
::Default { has_value: false }
,
437 AssocContainer
::TraitWithDefault
| AssocContainer
::ImplDefault
=> {
438 hir
::Defaultness
::Default { has_value: true }
441 AssocContainer
::ImplFinal
=> hir
::Defaultness
::Final
,
446 #[derive(MetadataEncodable, MetadataDecodable)]
449 container
: AssocContainer
,
453 #[derive(TyEncodable, TyDecodable)]
454 struct GeneratorData
<'tcx
> {
455 layout
: mir
::GeneratorLayout
<'tcx
>,
458 // Tags used for encoding Spans:
459 const TAG_VALID_SPAN_LOCAL
: u8 = 0;
460 const TAG_VALID_SPAN_FOREIGN
: u8 = 1;
461 const TAG_PARTIAL_SPAN
: u8 = 2;