2 use table
::{Table, TableBuilder}
;
4 use rustc_ast
::{self as ast, MacroDef}
;
5 use rustc_attr
as attr
;
6 use rustc_data_structures
::svh
::Svh
;
7 use rustc_data_structures
::sync
::MetadataRef
;
9 use rustc_hir
::def
::CtorKind
;
10 use rustc_hir
::def_id
::{DefId, DefIndex, DefPathHash}
;
11 use rustc_hir
::definitions
::DefKey
;
12 use rustc_hir
::lang_items
;
13 use rustc_index
::{bit_set::FiniteBitSet, vec::IndexVec}
;
14 use rustc_middle
::hir
::exports
::Export
;
15 use rustc_middle
::middle
::cstore
::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib}
;
16 use rustc_middle
::middle
::exported_symbols
::{ExportedSymbol, SymbolExportLevel}
;
17 use rustc_middle
::mir
;
18 use rustc_middle
::ty
::{self, ReprOptions, Ty}
;
19 use rustc_serialize
::opaque
::Encoder
;
20 use rustc_session
::config
::SymbolManglingVersion
;
21 use rustc_session
::CrateDisambiguator
;
22 use rustc_span
::edition
::Edition
;
23 use rustc_span
::symbol
::{Ident, Symbol}
;
24 use rustc_span
::{self, ExpnData, ExpnId, Span}
;
25 use rustc_target
::spec
::{PanicStrategy, TargetTriple}
;
27 use std
::marker
::PhantomData
;
28 use std
::num
::NonZeroUsize
;
30 use decoder
::DecodeContext
;
31 pub use decoder
::{provide, provide_extern}
;
32 crate use decoder
::{CrateMetadata, CrateNumMap, MetadataBlob}
;
33 use encoder
::EncodeContext
;
34 use rustc_span
::hygiene
::SyntaxContextData
;
40 crate fn rustc_version() -> String
{
41 format
!("rustc {}", option_env
!("CFG_VERSION").unwrap_or("unknown version"))
44 /// Metadata encoding version.
45 /// N.B., increment this if you change the format of metadata such that
46 /// the rustc version can't be found to compare with `rustc_version()`.
47 const METADATA_VERSION
: u8 = 5;
49 /// Metadata header which includes `METADATA_VERSION`.
51 /// This header is followed by the position of the `CrateRoot`,
52 /// which is encoded as a 32-bit big-endian unsigned integer,
53 /// and further followed by the rustc version string.
54 crate const METADATA_HEADER
: &[u8; 8] = &[b'r'
, b'u'
, b's'
, b't'
, 0, 0, 0, METADATA_VERSION
];
56 /// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
57 /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
59 type Meta
: Copy
+ '
static;
61 /// Returns the minimum encoded size.
62 // FIXME(eddyb) Give better estimates for certain types.
63 fn min_size(meta
: Self::Meta
) -> usize;
66 impl<T
> LazyMeta
for T
{
69 fn min_size(_
: ()) -> usize {
70 assert_ne
!(std
::mem
::size_of
::<T
>(), 0);
75 impl<T
> LazyMeta
for [T
] {
78 fn min_size(len
: usize) -> usize {
83 /// A value of type T referred to by its absolute position
84 /// in the metadata, and which can be decoded lazily.
86 /// Metadata is effective a tree, encoded in post-order,
87 /// and with the root's position written next to the header.
88 /// That means every single `Lazy` points to some previous
89 /// location in the metadata and is part of a larger node.
91 /// The first `Lazy` in a node is encoded as the backwards
92 /// distance from the position where the containing node
93 /// starts and where the `Lazy` points to, while the rest
94 /// use the forward distance from the previous `Lazy`.
95 /// Distances start at 1, as 0-byte nodes are invalid.
96 /// Also invalid are nodes being referred in a different
97 /// order than they were encoded in.
99 /// # Sequences (`Lazy<[T]>`)
101 /// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
102 /// position, not at the position, which means that the length
103 /// doesn't need to be known before encoding all the elements.
105 /// If the length is 0, no position is encoded, but otherwise,
106 /// the encoding is that of `Lazy`, with the distinction that
107 /// the minimal distance the length of the sequence, i.e.
108 /// it's assumed there's no 0-byte element in the sequence.
110 // FIXME(#59875) the `Meta` parameter only exists to dodge
111 // invariance wrt `T` (coming from the `meta: T::Meta` field).
112 struct Lazy
<T
, Meta
= <T
as LazyMeta
>::Meta
>
114 T
: ?Sized
+ LazyMeta
<Meta
= Meta
>,
115 Meta
: '
static + Copy
,
117 position
: NonZeroUsize
,
119 _marker
: PhantomData
<T
>,
122 impl<T
: ?Sized
+ LazyMeta
> Lazy
<T
> {
123 fn from_position_and_meta(position
: NonZeroUsize
, meta
: T
::Meta
) -> Lazy
<T
> {
124 Lazy { position, meta, _marker: PhantomData }
129 fn from_position(position
: NonZeroUsize
) -> Lazy
<T
> {
130 Lazy
::from_position_and_meta(position
, ())
135 fn empty() -> Lazy
<[T
]> {
136 Lazy
::from_position_and_meta(NonZeroUsize
::new(1).unwrap(), 0)
140 impl<T
: ?Sized
+ LazyMeta
> Copy
for Lazy
<T
> {}
141 impl<T
: ?Sized
+ LazyMeta
> Clone
for Lazy
<T
> {
142 fn clone(&self) -> Self {
147 /// Encoding / decoding state for `Lazy`.
148 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
150 /// Outside of a metadata node.
153 /// Inside a metadata node, and before any `Lazy`.
154 /// The position is that of the node itself.
155 NodeStart(NonZeroUsize
),
157 /// Inside a metadata node, with a previous `Lazy`.
158 /// The position is a conservative estimate of where that
159 /// previous `Lazy` would end (see their comments).
160 Previous(NonZeroUsize
),
163 // FIXME(#59875) `Lazy!(T)` replaces `Lazy<T>`, passing the `Meta` parameter
164 // manually, instead of relying on the default, to get the correct variance.
165 // Only needed when `T` itself contains a parameter (e.g. `'tcx`).
167 (Table
<$I
:ty
, $T
:ty
>) => {Lazy<Table<$I, $T>, usize>}
;
168 ([$T
:ty
]) => {Lazy<[$T], usize>}
;
169 ($T
:ty
) => {Lazy<$T, ()>}
;
172 type SyntaxContextTable
= Lazy
<Table
<u32, Lazy
<SyntaxContextData
>>>;
173 type ExpnDataTable
= Lazy
<Table
<u32, Lazy
<ExpnData
>>>;
175 #[derive(MetadataEncodable, MetadataDecodable)]
176 crate struct ProcMacroData
{
177 proc_macro_decls_static
: DefIndex
,
178 stability
: Option
<attr
::Stability
>,
179 macros
: Lazy
<[DefIndex
]>,
182 /// Serialized metadata for a crate.
183 /// When compiling a proc-macro crate, we encode many of
184 /// the `Lazy<[T]>` fields as `Lazy::empty()`. This serves two purposes:
186 /// 1. We avoid performing unnecessary work. Proc-macro crates can only
187 /// export proc-macros functions, which are compiled into a shared library.
188 /// As a result, a large amount of the information we normally store
189 /// (e.g. optimized MIR) is unneeded by downstream crates.
190 /// 2. We avoid serializing invalid `CrateNum`s. When we deserialize
191 /// a proc-macro crate, we don't load any of its dependencies (since we
192 /// just need to invoke a native function from the shared library).
193 /// This means that any foreign `CrateNum`s that we serialize cannot be
194 /// deserialized, since we will not know how to map them into the current
195 /// compilation session. If we were to serialize a proc-macro crate like
196 /// a normal crate, much of what we serialized would be unusable in addition
198 #[derive(MetadataEncodable, MetadataDecodable)]
199 crate struct CrateRoot
<'tcx
> {
201 triple
: TargetTriple
,
202 extra_filename
: String
,
204 disambiguator
: CrateDisambiguator
,
205 panic_strategy
: PanicStrategy
,
207 has_global_allocator
: bool
,
208 has_panic_handler
: bool
,
209 has_default_lib_allocator
: bool
,
210 plugin_registrar_fn
: Option
<DefIndex
>,
212 crate_deps
: Lazy
<[CrateDep
]>,
213 dylib_dependency_formats
: Lazy
<[Option
<LinkagePreference
>]>,
214 lib_features
: Lazy
<[(Symbol
, Option
<Symbol
>)]>,
215 lang_items
: Lazy
<[(DefIndex
, usize)]>,
216 lang_items_missing
: Lazy
<[lang_items
::LangItem
]>,
217 diagnostic_items
: Lazy
<[(Symbol
, DefIndex
)]>,
218 native_libraries
: Lazy
<[NativeLib
]>,
219 foreign_modules
: Lazy
<[ForeignModule
]>,
220 impls
: Lazy
<[TraitImpls
]>,
221 interpret_alloc_index
: Lazy
<[u32]>,
222 proc_macro_data
: Option
<ProcMacroData
>,
224 tables
: LazyTables
<'tcx
>,
226 exported_symbols
: Lazy
!([(ExportedSymbol
<'tcx
>, SymbolExportLevel
)]),
228 syntax_contexts
: SyntaxContextTable
,
229 expn_data
: ExpnDataTable
,
231 source_map
: Lazy
<[rustc_span
::SourceFile
]>,
233 compiler_builtins
: bool
,
234 needs_allocator
: bool
,
235 needs_panic_runtime
: bool
,
238 profiler_runtime
: bool
,
239 symbol_mangling_version
: SymbolManglingVersion
,
242 #[derive(Encodable, Decodable)]
243 crate struct CrateDep
{
246 pub host_hash
: Option
<Svh
>,
247 pub kind
: CrateDepKind
,
248 pub extra_filename
: String
,
251 #[derive(MetadataEncodable, MetadataDecodable)]
252 crate struct TraitImpls
{
253 trait_id
: (u32, DefIndex
),
254 impls
: Lazy
<[(DefIndex
, Option
<ty
::fast_reject
::SimplifiedType
>)]>,
257 /// Define `LazyTables` and `TableBuilders` at the same time.
258 macro_rules
! define_tables
{
259 ($
($name
:ident
: Table
<DefIndex
, $T
:ty
>),+ $
(,)?
) => {
260 #[derive(MetadataEncodable, MetadataDecodable)]
261 crate struct LazyTables
<'tcx
> {
262 $
($name
: Lazy
!(Table
<DefIndex
, $T
>)),+
266 struct TableBuilders
<'tcx
> {
267 $
($name
: TableBuilder
<DefIndex
, $T
>),+
270 impl TableBuilders
<'tcx
> {
271 fn encode(&self, buf
: &mut Encoder
) -> LazyTables
<'tcx
> {
273 $
($name
: self.$name
.encode(buf
)),+
281 kind
: Table
<DefIndex
, Lazy
<EntryKind
>>,
282 visibility
: Table
<DefIndex
, Lazy
<ty
::Visibility
>>,
283 span
: Table
<DefIndex
, Lazy
<Span
>>,
284 ident_span
: Table
<DefIndex
, Lazy
<Span
>>,
285 attributes
: Table
<DefIndex
, Lazy
<[ast
::Attribute
]>>,
286 children
: Table
<DefIndex
, Lazy
<[DefIndex
]>>,
287 stability
: Table
<DefIndex
, Lazy
<attr
::Stability
>>,
288 const_stability
: Table
<DefIndex
, Lazy
<attr
::ConstStability
>>,
289 deprecation
: Table
<DefIndex
, Lazy
<attr
::Deprecation
>>,
290 ty
: Table
<DefIndex
, Lazy
!(Ty
<'tcx
>)>,
291 fn_sig
: Table
<DefIndex
, Lazy
!(ty
::PolyFnSig
<'tcx
>)>,
292 impl_trait_ref
: Table
<DefIndex
, Lazy
!(ty
::TraitRef
<'tcx
>)>,
293 inherent_impls
: Table
<DefIndex
, Lazy
<[DefIndex
]>>,
294 variances
: Table
<DefIndex
, Lazy
<[ty
::Variance
]>>,
295 generics
: Table
<DefIndex
, Lazy
<ty
::Generics
>>,
296 explicit_predicates
: Table
<DefIndex
, Lazy
!(ty
::GenericPredicates
<'tcx
>)>,
297 // FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
298 // doesn't handle shorthands in its own (de)serialization impls,
299 // as it's an `enum` for which we want to derive (de)serialization,
300 // so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
301 // Also, as an optimization, a missing entry indicates an empty `&[]`.
302 inferred_outlives
: Table
<DefIndex
, Lazy
!(&'tcx
[(ty
::Predicate
<'tcx
>, Span
)])>,
303 super_predicates
: Table
<DefIndex
, Lazy
!(ty
::GenericPredicates
<'tcx
>)>,
304 mir
: Table
<DefIndex
, Lazy
!(mir
::Body
<'tcx
>)>,
305 promoted_mir
: Table
<DefIndex
, Lazy
!(IndexVec
<mir
::Promoted
, mir
::Body
<'tcx
>>)>,
306 mir_abstract_consts
: Table
<DefIndex
, Lazy
!(&'tcx
[mir
::abstract_const
::Node
<'tcx
>])>,
307 unused_generic_params
: Table
<DefIndex
, Lazy
<FiniteBitSet
<u32>>>,
308 // `def_keys` and `def_path_hashes` represent a lazy version of a
309 // `DefPathTable`. This allows us to avoid deserializing an entire
310 // `DefPathTable` up front, since we may only ever use a few
311 // definitions from any given crate.
312 def_keys
: Table
<DefIndex
, Lazy
<DefKey
>>,
313 def_path_hashes
: Table
<DefIndex
, Lazy
<DefPathHash
>>
316 #[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
318 AnonConst(mir
::ConstQualifs
, Lazy
<RenderedConst
>),
319 Const(mir
::ConstQualifs
, Lazy
<RenderedConst
>),
333 Variant(Lazy
<VariantData
>),
334 Struct(Lazy
<VariantData
>, ReprOptions
),
335 Union(Lazy
<VariantData
>, ReprOptions
),
337 ForeignFn(Lazy
<FnData
>),
339 MacroDef(Lazy
<MacroDef
>),
341 Generator(hir
::GeneratorKind
),
342 Trait(Lazy
<TraitData
>),
343 Impl(Lazy
<ImplData
>),
344 AssocFn(Lazy
<AssocFnData
>),
345 AssocType(AssocContainer
),
346 AssocConst(AssocContainer
, mir
::ConstQualifs
, Lazy
<RenderedConst
>),
350 /// Contains a constant which has been rendered to a String.
352 #[derive(Encodable, Decodable)]
353 struct RenderedConst(String
);
355 #[derive(MetadataEncodable, MetadataDecodable)]
357 reexports
: Lazy
<[Export
<hir
::HirId
>]>,
361 #[derive(MetadataEncodable, MetadataDecodable)]
363 asyncness
: hir
::IsAsync
,
364 constness
: hir
::Constness
,
365 param_names
: Lazy
<[Ident
]>,
368 #[derive(TyEncodable, TyDecodable)]
371 discr
: ty
::VariantDiscr
,
372 /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
373 ctor
: Option
<DefIndex
>,
374 is_non_exhaustive
: bool
,
377 #[derive(TyEncodable, TyDecodable)]
379 unsafety
: hir
::Unsafety
,
383 specialization_kind
: ty
::trait_def
::TraitSpecializationKind
,
386 #[derive(TyEncodable, TyDecodable)]
388 polarity
: ty
::ImplPolarity
,
389 defaultness
: hir
::Defaultness
,
390 parent_impl
: Option
<DefId
>,
392 /// This is `Some` only for impls of `CoerceUnsized`.
393 // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
394 coerce_unsized_info
: Option
<ty
::adjustment
::CoerceUnsizedInfo
>,
397 /// Describes whether the container of an associated item
398 /// is a trait or an impl and whether, in a trait, it has
399 /// a default, or an in impl, whether it's marked "default".
400 #[derive(Copy, Clone, TyEncodable, TyDecodable)]
401 enum AssocContainer
{
408 impl AssocContainer
{
409 fn with_def_id(&self, def_id
: DefId
) -> ty
::AssocItemContainer
{
411 AssocContainer
::TraitRequired
| AssocContainer
::TraitWithDefault
=> {
412 ty
::TraitContainer(def_id
)
415 AssocContainer
::ImplDefault
| AssocContainer
::ImplFinal
=> ty
::ImplContainer(def_id
),
419 fn defaultness(&self) -> hir
::Defaultness
{
421 AssocContainer
::TraitRequired
=> hir
::Defaultness
::Default { has_value: false }
,
423 AssocContainer
::TraitWithDefault
| AssocContainer
::ImplDefault
=> {
424 hir
::Defaultness
::Default { has_value: true }
427 AssocContainer
::ImplFinal
=> hir
::Defaultness
::Final
,
432 #[derive(MetadataEncodable, MetadataDecodable)]
435 container
: AssocContainer
,
439 #[derive(TyEncodable, TyDecodable)]
440 struct GeneratorData
<'tcx
> {
441 layout
: mir
::GeneratorLayout
<'tcx
>,
444 // Tags used for encoding Spans:
445 const TAG_VALID_SPAN_LOCAL
: u8 = 0;
446 const TAG_VALID_SPAN_FOREIGN
: u8 = 1;
447 const TAG_INVALID_SPAN
: u8 = 2;