2 use table
::{Table, TableBuilder}
;
4 use rustc
::hir
::exports
::Export
;
6 use rustc
::middle
::cstore
::{DepKind, ForeignModule, LinkagePreference, NativeLibrary}
;
7 use rustc
::middle
::exported_symbols
::{ExportedSymbol, SymbolExportLevel}
;
8 use rustc
::middle
::lang_items
;
10 use rustc
::session
::config
::SymbolManglingVersion
;
11 use rustc
::session
::CrateDisambiguator
;
12 use rustc
::ty
::{self, ReprOptions, Ty}
;
14 use rustc_attr
as attr
;
15 use rustc_data_structures
::svh
::Svh
;
16 use rustc_data_structures
::sync
::MetadataRef
;
18 use rustc_hir
::def
::CtorKind
;
19 use rustc_hir
::def_id
::{DefId, DefIndex}
;
20 use rustc_index
::vec
::IndexVec
;
21 use rustc_serialize
::opaque
::Encoder
;
22 use rustc_span
::edition
::Edition
;
23 use rustc_span
::symbol
::Symbol
;
24 use rustc_span
::{self, Span}
;
25 use rustc_target
::spec
::{PanicStrategy, TargetTriple}
;
27 use std
::marker
::PhantomData
;
28 use std
::num
::NonZeroUsize
;
30 pub use decoder
::{provide, provide_extern}
;
31 crate use decoder
::{CrateMetadata, CrateNumMap, MetadataBlob}
;
37 crate fn rustc_version() -> String
{
38 format
!("rustc {}", option_env
!("CFG_VERSION").unwrap_or("unknown version"))
41 /// Metadata encoding version.
42 /// N.B., increment this if you change the format of metadata such that
43 /// the rustc version can't be found to compare with `rustc_version()`.
44 const METADATA_VERSION
: u8 = 5;
46 /// Metadata header which includes `METADATA_VERSION`.
48 /// This header is followed by the position of the `CrateRoot`,
49 /// which is encoded as a 32-bit big-endian unsigned integer,
50 /// and further followed by the rustc version string.
51 crate const METADATA_HEADER
: &[u8; 8] = &[b'r'
, b'u'
, b's'
, b't'
, 0, 0, 0, METADATA_VERSION
];
53 /// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
54 /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
56 type Meta
: Copy
+ '
static;
58 /// Returns the minimum encoded size.
59 // FIXME(eddyb) Give better estimates for certain types.
60 fn min_size(meta
: Self::Meta
) -> usize;
63 impl<T
> LazyMeta
for T
{
66 fn min_size(_
: ()) -> usize {
67 assert_ne
!(std
::mem
::size_of
::<T
>(), 0);
72 impl<T
> LazyMeta
for [T
] {
75 fn min_size(len
: usize) -> usize {
80 /// A value of type T referred to by its absolute position
81 /// in the metadata, and which can be decoded lazily.
83 /// Metadata is effective a tree, encoded in post-order,
84 /// and with the root's position written next to the header.
85 /// That means every single `Lazy` points to some previous
86 /// location in the metadata and is part of a larger node.
88 /// The first `Lazy` in a node is encoded as the backwards
89 /// distance from the position where the containing node
90 /// starts and where the `Lazy` points to, while the rest
91 /// use the forward distance from the previous `Lazy`.
92 /// Distances start at 1, as 0-byte nodes are invalid.
93 /// Also invalid are nodes being referred in a different
94 /// order than they were encoded in.
96 /// # Sequences (`Lazy<[T]>`)
98 /// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
99 /// position, not at the position, which means that the length
100 /// doesn't need to be known before encoding all the elements.
102 /// If the length is 0, no position is encoded, but otherwise,
103 /// the encoding is that of `Lazy`, with the distinction that
104 /// the minimal distance the length of the sequence, i.e.
105 /// it's assumed there's no 0-byte element in the sequence.
107 // FIXME(#59875) the `Meta` parameter only exists to dodge
108 // invariance wrt `T` (coming from the `meta: T::Meta` field).
109 struct Lazy
<T
, Meta
= <T
as LazyMeta
>::Meta
>
111 T
: ?Sized
+ LazyMeta
<Meta
= Meta
>,
112 Meta
: '
static + Copy
,
114 position
: NonZeroUsize
,
116 _marker
: PhantomData
<T
>,
119 impl<T
: ?Sized
+ LazyMeta
> Lazy
<T
> {
120 fn from_position_and_meta(position
: NonZeroUsize
, meta
: T
::Meta
) -> Lazy
<T
> {
121 Lazy { position, meta, _marker: PhantomData }
126 fn from_position(position
: NonZeroUsize
) -> Lazy
<T
> {
127 Lazy
::from_position_and_meta(position
, ())
132 fn empty() -> Lazy
<[T
]> {
133 Lazy
::from_position_and_meta(NonZeroUsize
::new(1).unwrap(), 0)
137 impl<T
: ?Sized
+ LazyMeta
> Copy
for Lazy
<T
> {}
138 impl<T
: ?Sized
+ LazyMeta
> Clone
for Lazy
<T
> {
139 fn clone(&self) -> Self {
144 impl<T
: ?Sized
+ LazyMeta
> rustc_serialize
::UseSpecializedEncodable
for Lazy
<T
> {}
145 impl<T
: ?Sized
+ LazyMeta
> rustc_serialize
::UseSpecializedDecodable
for Lazy
<T
> {}
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 #[derive(RustcEncodable, RustcDecodable)]
173 crate struct CrateRoot
<'tcx
> {
175 triple
: TargetTriple
,
176 extra_filename
: String
,
178 disambiguator
: CrateDisambiguator
,
179 panic_strategy
: PanicStrategy
,
181 has_global_allocator
: bool
,
182 has_panic_handler
: bool
,
183 has_default_lib_allocator
: bool
,
184 plugin_registrar_fn
: Option
<DefIndex
>,
185 proc_macro_decls_static
: Option
<DefIndex
>,
186 proc_macro_stability
: Option
<attr
::Stability
>,
188 crate_deps
: Lazy
<[CrateDep
]>,
189 dylib_dependency_formats
: Lazy
<[Option
<LinkagePreference
>]>,
190 lib_features
: Lazy
<[(Symbol
, Option
<Symbol
>)]>,
191 lang_items
: Lazy
<[(DefIndex
, usize)]>,
192 lang_items_missing
: Lazy
<[lang_items
::LangItem
]>,
193 diagnostic_items
: Lazy
<[(Symbol
, DefIndex
)]>,
194 native_libraries
: Lazy
<[NativeLibrary
]>,
195 foreign_modules
: Lazy
<[ForeignModule
]>,
196 source_map
: Lazy
<[rustc_span
::SourceFile
]>,
197 def_path_table
: Lazy
<map
::definitions
::DefPathTable
>,
198 impls
: Lazy
<[TraitImpls
]>,
199 exported_symbols
: Lazy
!([(ExportedSymbol
<'tcx
>, SymbolExportLevel
)]),
200 interpret_alloc_index
: Lazy
<[u32]>,
202 per_def
: LazyPerDefTables
<'tcx
>,
204 /// The DefIndex's of any proc macros declared by this crate.
205 proc_macro_data
: Option
<Lazy
<[DefIndex
]>>,
207 compiler_builtins
: bool
,
208 needs_allocator
: bool
,
209 needs_panic_runtime
: bool
,
212 profiler_runtime
: bool
,
213 symbol_mangling_version
: SymbolManglingVersion
,
216 #[derive(RustcEncodable, RustcDecodable)]
217 crate struct CrateDep
{
220 pub host_hash
: Option
<Svh
>,
222 pub extra_filename
: String
,
225 #[derive(RustcEncodable, RustcDecodable)]
226 crate struct TraitImpls
{
227 trait_id
: (u32, DefIndex
),
228 impls
: Lazy
<[DefIndex
]>,
231 /// Define `LazyPerDefTables` and `PerDefTableBuilders` at the same time.
232 macro_rules
! define_per_def_tables
{
233 ($
($name
:ident
: Table
<DefIndex
, $T
:ty
>),+ $
(,)?
) => {
234 #[derive(RustcEncodable, RustcDecodable)]
235 crate struct LazyPerDefTables
<'tcx
> {
236 $
($name
: Lazy
!(Table
<DefIndex
, $T
>)),+
240 struct PerDefTableBuilders
<'tcx
> {
241 $
($name
: TableBuilder
<DefIndex
, $T
>),+
244 impl PerDefTableBuilders
<'tcx
> {
245 fn encode(&self, buf
: &mut Encoder
) -> LazyPerDefTables
<'tcx
> {
247 $
($name
: self.$name
.encode(buf
)),+
254 define_per_def_tables
! {
255 kind
: Table
<DefIndex
, Lazy
<EntryKind
>>,
256 visibility
: Table
<DefIndex
, Lazy
<ty
::Visibility
>>,
257 span
: Table
<DefIndex
, Lazy
<Span
>>,
258 attributes
: Table
<DefIndex
, Lazy
<[ast
::Attribute
]>>,
259 children
: Table
<DefIndex
, Lazy
<[DefIndex
]>>,
260 stability
: Table
<DefIndex
, Lazy
<attr
::Stability
>>,
261 const_stability
: Table
<DefIndex
, Lazy
<attr
::ConstStability
>>,
262 deprecation
: Table
<DefIndex
, Lazy
<attr
::Deprecation
>>,
263 ty
: Table
<DefIndex
, Lazy
!(Ty
<'tcx
>)>,
264 fn_sig
: Table
<DefIndex
, Lazy
!(ty
::PolyFnSig
<'tcx
>)>,
265 impl_trait_ref
: Table
<DefIndex
, Lazy
!(ty
::TraitRef
<'tcx
>)>,
266 inherent_impls
: Table
<DefIndex
, Lazy
<[DefIndex
]>>,
267 variances
: Table
<DefIndex
, Lazy
<[ty
::Variance
]>>,
268 generics
: Table
<DefIndex
, Lazy
<ty
::Generics
>>,
269 explicit_predicates
: Table
<DefIndex
, Lazy
!(ty
::GenericPredicates
<'tcx
>)>,
270 // FIXME(eddyb) this would ideally be `Lazy<[...]>` but `ty::Predicate`
271 // doesn't handle shorthands in its own (de)serialization impls,
272 // as it's an `enum` for which we want to derive (de)serialization,
273 // so the `ty::codec` APIs handle the whole `&'tcx [...]` at once.
274 // Also, as an optimization, a missing entry indicates an empty `&[]`.
275 inferred_outlives
: Table
<DefIndex
, Lazy
!(&'tcx
[(ty
::Predicate
<'tcx
>, Span
)])>,
276 super_predicates
: Table
<DefIndex
, Lazy
!(ty
::GenericPredicates
<'tcx
>)>,
277 mir
: Table
<DefIndex
, Lazy
!(mir
::BodyAndCache
<'tcx
>)>,
278 promoted_mir
: Table
<DefIndex
, Lazy
!(IndexVec
<mir
::Promoted
, mir
::BodyAndCache
<'tcx
>>)>,
281 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
283 Const(mir
::ConstQualifs
, Lazy
<RenderedConst
>),
297 Variant(Lazy
<VariantData
>),
298 Struct(Lazy
<VariantData
>, ReprOptions
),
299 Union(Lazy
<VariantData
>, ReprOptions
),
301 ForeignFn(Lazy
<FnData
>),
303 MacroDef(Lazy
<MacroDef
>),
305 Generator(hir
::GeneratorKind
),
306 Trait(Lazy
<TraitData
>),
307 Impl(Lazy
<ImplData
>),
308 Method(Lazy
<MethodData
>),
309 AssocType(AssocContainer
),
310 AssocOpaqueTy(AssocContainer
),
311 AssocConst(AssocContainer
, mir
::ConstQualifs
, Lazy
<RenderedConst
>),
315 /// Contains a constant which has been rendered to a String.
317 #[derive(RustcEncodable, RustcDecodable)]
318 struct RenderedConst(String
);
320 #[derive(RustcEncodable, RustcDecodable)]
322 reexports
: Lazy
<[Export
<hir
::HirId
>]>,
325 #[derive(RustcEncodable, RustcDecodable)]
331 #[derive(RustcEncodable, RustcDecodable)]
333 asyncness
: hir
::IsAsync
,
334 constness
: hir
::Constness
,
335 param_names
: Lazy
<[ast
::Name
]>,
338 #[derive(RustcEncodable, RustcDecodable)]
341 discr
: ty
::VariantDiscr
,
342 /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
343 ctor
: Option
<DefIndex
>,
346 #[derive(RustcEncodable, RustcDecodable)]
348 unsafety
: hir
::Unsafety
,
354 #[derive(RustcEncodable, RustcDecodable)]
356 polarity
: ty
::ImplPolarity
,
357 defaultness
: hir
::Defaultness
,
358 parent_impl
: Option
<DefId
>,
360 /// This is `Some` only for impls of `CoerceUnsized`.
361 // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
362 coerce_unsized_info
: Option
<ty
::adjustment
::CoerceUnsizedInfo
>,
365 /// Describes whether the container of an associated item
366 /// is a trait or an impl and whether, in a trait, it has
367 /// a default, or an in impl, whether it's marked "default".
368 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
369 enum AssocContainer
{
376 impl AssocContainer
{
377 fn with_def_id(&self, def_id
: DefId
) -> ty
::AssocItemContainer
{
379 AssocContainer
::TraitRequired
| AssocContainer
::TraitWithDefault
=> {
380 ty
::TraitContainer(def_id
)
383 AssocContainer
::ImplDefault
| AssocContainer
::ImplFinal
=> ty
::ImplContainer(def_id
),
387 fn defaultness(&self) -> hir
::Defaultness
{
389 AssocContainer
::TraitRequired
=> hir
::Defaultness
::Default { has_value: false }
,
391 AssocContainer
::TraitWithDefault
| AssocContainer
::ImplDefault
=> {
392 hir
::Defaultness
::Default { has_value: true }
395 AssocContainer
::ImplFinal
=> hir
::Defaultness
::Final
,
400 #[derive(RustcEncodable, RustcDecodable)]
403 container
: AssocContainer
,
407 #[derive(RustcEncodable, RustcDecodable)]
408 struct GeneratorData
<'tcx
> {
409 layout
: mir
::GeneratorLayout
<'tcx
>,
412 // Tags used for encoding Spans:
413 const TAG_VALID_SPAN
: u8 = 0;
414 const TAG_INVALID_SPAN
: u8 = 1;