4 use rustc
::hir
::def
::{self, CtorKind}
;
5 use rustc
::hir
::def_id
::{DefIndex, DefId, CrateNum}
;
6 use rustc
::ich
::StableHashingContext
;
7 use rustc
::middle
::cstore
::{DepKind, LinkagePreference, NativeLibrary, ForeignModule}
;
8 use rustc
::middle
::lang_items
;
10 use rustc
::session
::CrateDisambiguator
;
11 use rustc
::ty
::{self, Ty, ReprOptions}
;
12 use rustc_target
::spec
::{PanicStrategy, TargetTriple}
;
13 use rustc_data_structures
::svh
::Svh
;
15 use rustc_serialize
as serialize
;
16 use syntax
::{ast, attr}
;
17 use syntax
::edition
::Edition
;
18 use syntax
::symbol
::Symbol
;
19 use syntax_pos
::{self, Span}
;
21 use std
::marker
::PhantomData
;
24 use rustc_data_structures
::stable_hasher
::{StableHasher
, HashStable
,
27 pub fn rustc_version() -> String
{
29 option_env
!("CFG_VERSION").unwrap_or("unknown version"))
32 /// Metadata encoding version.
33 /// N.B., increment this if you change the format of metadata such that
34 /// the rustc version can't be found to compare with `rustc_version()`.
35 pub const METADATA_VERSION
: u8 = 4;
37 /// Metadata header which includes `METADATA_VERSION`.
38 /// To get older versions of rustc to ignore this metadata,
39 /// there are 4 zero bytes at the start, which are treated
40 /// as a length of 0 by old compilers.
42 /// This header is followed by the position of the `CrateRoot`,
43 /// which is encoded as a 32-bit big-endian unsigned integer,
44 /// and further followed by the rustc version string.
45 pub const METADATA_HEADER
: &[u8; 12] =
46 &[0, 0, 0, 0, b'r'
, b'u'
, b's'
, b't'
, 0, 0, 0, METADATA_VERSION
];
48 /// A value of type T referred to by its absolute position
49 /// in the metadata, and which can be decoded lazily.
51 /// Metadata is effective a tree, encoded in post-order,
52 /// and with the root's position written next to the header.
53 /// That means every single `Lazy` points to some previous
54 /// location in the metadata and is part of a larger node.
56 /// The first `Lazy` in a node is encoded as the backwards
57 /// distance from the position where the containing node
58 /// starts and where the `Lazy` points to, while the rest
59 /// use the forward distance from the previous `Lazy`.
60 /// Distances start at 1, as 0-byte nodes are invalid.
61 /// Also invalid are nodes being referred in a different
62 /// order than they were encoded in.
66 _marker
: PhantomData
<T
>,
70 pub fn with_position(position
: usize) -> Lazy
<T
> {
77 /// Returns the minimum encoded size of a value of type `T`.
78 // FIXME(eddyb) Give better estimates for certain types.
79 pub fn min_size() -> usize {
84 impl<T
> Copy
for Lazy
<T
> {}
85 impl<T
> Clone
for Lazy
<T
> {
86 fn clone(&self) -> Self {
91 impl<T
> serialize
::UseSpecializedEncodable
for Lazy
<T
> {}
92 impl<T
> serialize
::UseSpecializedDecodable
for Lazy
<T
> {}
94 impl<CTX
, T
> HashStable
<CTX
> for Lazy
<T
> {
95 fn hash_stable
<W
: StableHasherResult
>(&self,
97 _
: &mut StableHasher
<W
>) {
98 // There's nothing to do. Whatever got encoded within this Lazy<>
99 // wrapper has already been hashed.
103 /// A sequence of type T referred to by its absolute position
104 /// in the metadata and length, and which can be decoded lazily.
105 /// The sequence is a single node for the purposes of `Lazy`.
107 /// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
108 /// position, not at the position, which means that the length
109 /// doesn't need to be known before encoding all the elements.
111 /// If the length is 0, no position is encoded, but otherwise,
112 /// the encoding is that of `Lazy`, with the distinction that
113 /// the minimal distance the length of the sequence, i.e.
114 /// it's assumed there's no 0-byte element in the sequence.
116 pub struct LazySeq
<T
> {
119 _marker
: PhantomData
<T
>,
123 pub fn empty() -> LazySeq
<T
> {
124 LazySeq
::with_position_and_length(0, 0)
127 pub fn with_position_and_length(position
: usize, len
: usize) -> LazySeq
<T
> {
131 _marker
: PhantomData
,
135 /// Returns the minimum encoded size of `length` values of type `T`.
136 pub fn min_size(length
: usize) -> usize {
141 impl<T
> Copy
for LazySeq
<T
> {}
142 impl<T
> Clone
for LazySeq
<T
> {
143 fn clone(&self) -> Self {
148 impl<T
> serialize
::UseSpecializedEncodable
for LazySeq
<T
> {}
149 impl<T
> serialize
::UseSpecializedDecodable
for LazySeq
<T
> {}
151 impl<CTX
, T
> HashStable
<CTX
> for LazySeq
<T
> {
152 fn hash_stable
<W
: StableHasherResult
>(&self,
154 _
: &mut StableHasher
<W
>) {
155 // There's nothing to do. Whatever got encoded within this Lazy<>
156 // wrapper has already been hashed.
160 /// Encoding / decoding state for `Lazy` and `LazySeq`.
161 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
163 /// Outside of a metadata node.
166 /// Inside a metadata node, and before any `Lazy` or `LazySeq`.
167 /// The position is that of the node itself.
170 /// Inside a metadata node, with a previous `Lazy` or `LazySeq`.
171 /// The position is a conservative estimate of where that
172 /// previous `Lazy` / `LazySeq` would end (see their comments).
176 #[derive(RustcEncodable, RustcDecodable)]
177 pub struct CrateRoot
{
179 pub triple
: TargetTriple
,
180 pub extra_filename
: String
,
182 pub disambiguator
: CrateDisambiguator
,
183 pub panic_strategy
: PanicStrategy
,
184 pub edition
: Edition
,
185 pub has_global_allocator
: bool
,
186 pub has_panic_handler
: bool
,
187 pub has_default_lib_allocator
: bool
,
188 pub plugin_registrar_fn
: Option
<DefIndex
>,
189 pub proc_macro_decls_static
: Option
<DefIndex
>,
191 pub crate_deps
: LazySeq
<CrateDep
>,
192 pub dylib_dependency_formats
: LazySeq
<Option
<LinkagePreference
>>,
193 pub lib_features
: LazySeq
<(Symbol
, Option
<Symbol
>)>,
194 pub lang_items
: LazySeq
<(DefIndex
, usize)>,
195 pub lang_items_missing
: LazySeq
<lang_items
::LangItem
>,
196 pub native_libraries
: LazySeq
<NativeLibrary
>,
197 pub foreign_modules
: LazySeq
<ForeignModule
>,
198 pub source_map
: LazySeq
<syntax_pos
::SourceFile
>,
199 pub def_path_table
: Lazy
<hir
::map
::definitions
::DefPathTable
>,
200 pub impls
: LazySeq
<TraitImpls
>,
201 pub exported_symbols
: EncodedExportedSymbols
,
202 pub interpret_alloc_index
: LazySeq
<u32>,
204 pub index
: LazySeq
<index
::Index
>,
206 pub compiler_builtins
: bool
,
207 pub needs_allocator
: bool
,
208 pub needs_panic_runtime
: bool
,
209 pub no_builtins
: bool
,
210 pub panic_runtime
: bool
,
211 pub profiler_runtime
: bool
,
212 pub sanitizer_runtime
: bool
,
215 #[derive(RustcEncodable, RustcDecodable)]
216 pub struct CrateDep
{
220 pub extra_filename
: String
,
223 impl_stable_hash_for
!(struct CrateDep
{
230 #[derive(RustcEncodable, RustcDecodable)]
231 pub struct TraitImpls
{
232 pub trait_id
: (u32, DefIndex
),
233 pub impls
: LazySeq
<DefIndex
>,
236 impl<'a
, 'gcx
> HashStable
<StableHashingContext
<'a
>> for TraitImpls
{
237 fn hash_stable
<W
: StableHasherResult
>(&self,
238 hcx
: &mut StableHashingContext
<'a
>,
239 hasher
: &mut StableHasher
<W
>) {
241 trait_id
: (krate
, def_index
),
246 krate
: CrateNum
::from_u32(krate
),
248 }.hash_stable(hcx
, hasher
);
249 impls
.hash_stable(hcx
, hasher
);
253 #[derive(RustcEncodable, RustcDecodable)]
254 pub struct Entry
<'tcx
> {
255 pub kind
: EntryKind
<'tcx
>,
256 pub visibility
: Lazy
<ty
::Visibility
>,
257 pub span
: Lazy
<Span
>,
258 pub attributes
: LazySeq
<ast
::Attribute
>,
259 pub children
: LazySeq
<DefIndex
>,
260 pub stability
: Option
<Lazy
<attr
::Stability
>>,
261 pub deprecation
: Option
<Lazy
<attr
::Deprecation
>>,
263 pub ty
: Option
<Lazy
<Ty
<'tcx
>>>,
264 pub inherent_impls
: LazySeq
<DefIndex
>,
265 pub variances
: LazySeq
<ty
::Variance
>,
266 pub generics
: Option
<Lazy
<ty
::Generics
>>,
267 pub predicates
: Option
<Lazy
<ty
::GenericPredicates
<'tcx
>>>,
268 pub predicates_defined_on
: Option
<Lazy
<ty
::GenericPredicates
<'tcx
>>>,
270 pub mir
: Option
<Lazy
<mir
::Mir
<'tcx
>>>,
273 impl_stable_hash_for
!(struct Entry
<'tcx
> {
286 predicates_defined_on
,
290 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
291 pub enum EntryKind
<'tcx
> {
292 Const(ConstQualif
, Lazy
<RenderedConst
>),
304 Variant(Lazy
<VariantData
<'tcx
>>),
305 Struct(Lazy
<VariantData
<'tcx
>>, ReprOptions
),
306 Union(Lazy
<VariantData
<'tcx
>>, ReprOptions
),
307 Fn(Lazy
<FnData
<'tcx
>>),
308 ForeignFn(Lazy
<FnData
<'tcx
>>),
310 MacroDef(Lazy
<MacroDef
>),
311 Closure(Lazy
<ClosureData
<'tcx
>>),
312 Generator(Lazy
<GeneratorData
<'tcx
>>),
313 Trait(Lazy
<TraitData
<'tcx
>>),
314 Impl(Lazy
<ImplData
<'tcx
>>),
315 Method(Lazy
<MethodData
<'tcx
>>),
316 AssociatedType(AssociatedContainer
),
317 AssociatedExistential(AssociatedContainer
),
318 AssociatedConst(AssociatedContainer
, ConstQualif
, Lazy
<RenderedConst
>),
321 impl<'a
, 'gcx
> HashStable
<StableHashingContext
<'a
>> for EntryKind
<'gcx
> {
322 fn hash_stable
<W
: StableHasherResult
>(&self,
323 hcx
: &mut StableHashingContext
<'a
>,
324 hasher
: &mut StableHasher
<W
>) {
325 mem
::discriminant(self).hash_stable(hcx
, hasher
);
327 EntryKind
::ImmStatic
|
328 EntryKind
::MutStatic
|
329 EntryKind
::ForeignImmStatic
|
330 EntryKind
::ForeignMutStatic
|
331 EntryKind
::ForeignMod
|
332 EntryKind
::GlobalAsm
|
333 EntryKind
::ForeignType
|
335 EntryKind
::Existential
|
337 // Nothing else to hash here.
339 EntryKind
::Const(qualif
, ref const_data
) => {
340 qualif
.hash_stable(hcx
, hasher
);
341 const_data
.hash_stable(hcx
, hasher
);
343 EntryKind
::Enum(ref repr_options
) => {
344 repr_options
.hash_stable(hcx
, hasher
);
346 EntryKind
::Variant(ref variant_data
) => {
347 variant_data
.hash_stable(hcx
, hasher
);
349 EntryKind
::Struct(ref variant_data
, ref repr_options
) |
350 EntryKind
::Union(ref variant_data
, ref repr_options
) => {
351 variant_data
.hash_stable(hcx
, hasher
);
352 repr_options
.hash_stable(hcx
, hasher
);
354 EntryKind
::Fn(ref fn_data
) |
355 EntryKind
::ForeignFn(ref fn_data
) => {
356 fn_data
.hash_stable(hcx
, hasher
);
358 EntryKind
::Mod(ref mod_data
) => {
359 mod_data
.hash_stable(hcx
, hasher
);
361 EntryKind
::MacroDef(ref macro_def
) => {
362 macro_def
.hash_stable(hcx
, hasher
);
364 EntryKind
::Generator(data
) => {
365 data
.hash_stable(hcx
, hasher
);
367 EntryKind
::Closure(closure_data
) => {
368 closure_data
.hash_stable(hcx
, hasher
);
370 EntryKind
::Trait(ref trait_data
) => {
371 trait_data
.hash_stable(hcx
, hasher
);
373 EntryKind
::Impl(ref impl_data
) => {
374 impl_data
.hash_stable(hcx
, hasher
);
376 EntryKind
::Method(ref method_data
) => {
377 method_data
.hash_stable(hcx
, hasher
);
379 EntryKind
::AssociatedExistential(associated_container
) |
380 EntryKind
::AssociatedType(associated_container
) => {
381 associated_container
.hash_stable(hcx
, hasher
);
383 EntryKind
::AssociatedConst(associated_container
, qualif
, ref const_data
) => {
384 associated_container
.hash_stable(hcx
, hasher
);
385 qualif
.hash_stable(hcx
, hasher
);
386 const_data
.hash_stable(hcx
, hasher
);
392 /// Additional data for EntryKind::Const and EntryKind::AssociatedConst
393 #[derive(Clone, Copy, RustcEncodable, RustcDecodable)]
394 pub struct ConstQualif
{
396 pub ast_promotable
: bool
,
399 impl_stable_hash_for
!(struct ConstQualif { mir, ast_promotable }
);
401 /// Contains a constant which has been rendered to a String.
403 #[derive(RustcEncodable, RustcDecodable)]
404 pub struct RenderedConst(pub String
);
406 impl<'a
> HashStable
<StableHashingContext
<'a
>> for RenderedConst
{
408 fn hash_stable
<W
: StableHasherResult
>(&self,
409 hcx
: &mut StableHashingContext
<'a
>,
410 hasher
: &mut StableHasher
<W
>) {
411 self.0.hash_stable(hcx
, hasher
);
415 #[derive(RustcEncodable, RustcDecodable)]
417 pub reexports
: LazySeq
<def
::Export
>,
420 impl_stable_hash_for
!(struct ModData { reexports }
);
422 #[derive(RustcEncodable, RustcDecodable)]
423 pub struct MacroDef
{
428 impl_stable_hash_for
!(struct MacroDef { body, legacy }
);
430 #[derive(RustcEncodable, RustcDecodable)]
431 pub struct FnData
<'tcx
> {
432 pub constness
: hir
::Constness
,
433 pub arg_names
: LazySeq
<ast
::Name
>,
434 pub sig
: Lazy
<ty
::PolyFnSig
<'tcx
>>,
437 impl_stable_hash_for
!(struct FnData
<'tcx
> { constness, arg_names, sig }
);
439 #[derive(RustcEncodable, RustcDecodable)]
440 pub struct VariantData
<'tcx
> {
441 pub ctor_kind
: CtorKind
,
442 pub discr
: ty
::VariantDiscr
,
444 /// If this is a struct's only variant, this
445 /// is the index of the "struct ctor" item.
446 pub struct_ctor
: Option
<DefIndex
>,
448 /// If this is a tuple struct or variant
449 /// ctor, this is its "function" signature.
450 pub ctor_sig
: Option
<Lazy
<ty
::PolyFnSig
<'tcx
>>>,
453 impl_stable_hash_for
!(struct VariantData
<'tcx
> {
460 #[derive(RustcEncodable, RustcDecodable)]
461 pub struct TraitData
<'tcx
> {
462 pub unsafety
: hir
::Unsafety
,
463 pub paren_sugar
: bool
,
464 pub has_auto_impl
: bool
,
466 pub super_predicates
: Lazy
<ty
::GenericPredicates
<'tcx
>>,
469 impl_stable_hash_for
!(struct TraitData
<'tcx
> {
477 #[derive(RustcEncodable, RustcDecodable)]
478 pub struct ImplData
<'tcx
> {
479 pub polarity
: hir
::ImplPolarity
,
480 pub defaultness
: hir
::Defaultness
,
481 pub parent_impl
: Option
<DefId
>,
483 /// This is `Some` only for impls of `CoerceUnsized`.
484 pub coerce_unsized_info
: Option
<ty
::adjustment
::CoerceUnsizedInfo
>,
485 pub trait_ref
: Option
<Lazy
<ty
::TraitRef
<'tcx
>>>,
488 impl_stable_hash_for
!(struct ImplData
<'tcx
> {
497 /// Describes whether the container of an associated item
498 /// is a trait or an impl and whether, in a trait, it has
499 /// a default, or an in impl, whether it's marked "default".
500 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
501 pub enum AssociatedContainer
{
508 impl_stable_hash_for
!(enum ::schema
::AssociatedContainer
{
515 impl AssociatedContainer
{
516 pub fn with_def_id(&self, def_id
: DefId
) -> ty
::AssociatedItemContainer
{
518 AssociatedContainer
::TraitRequired
|
519 AssociatedContainer
::TraitWithDefault
=> ty
::TraitContainer(def_id
),
521 AssociatedContainer
::ImplDefault
|
522 AssociatedContainer
::ImplFinal
=> ty
::ImplContainer(def_id
),
526 pub fn defaultness(&self) -> hir
::Defaultness
{
528 AssociatedContainer
::TraitRequired
=> hir
::Defaultness
::Default
{
532 AssociatedContainer
::TraitWithDefault
|
533 AssociatedContainer
::ImplDefault
=> hir
::Defaultness
::Default
{
537 AssociatedContainer
::ImplFinal
=> hir
::Defaultness
::Final
,
542 #[derive(RustcEncodable, RustcDecodable)]
543 pub struct MethodData
<'tcx
> {
544 pub fn_data
: FnData
<'tcx
>,
545 pub container
: AssociatedContainer
,
548 impl_stable_hash_for
!(struct MethodData
<'tcx
> { fn_data, container, has_self }
);
550 #[derive(RustcEncodable, RustcDecodable)]
551 pub struct ClosureData
<'tcx
> {
552 pub sig
: Lazy
<ty
::PolyFnSig
<'tcx
>>,
554 impl_stable_hash_for
!(struct ClosureData
<'tcx
> { sig }
);
556 #[derive(RustcEncodable, RustcDecodable)]
557 pub struct GeneratorData
<'tcx
> {
558 pub layout
: mir
::GeneratorLayout
<'tcx
>,
560 impl_stable_hash_for
!(struct GeneratorData
<'tcx
> { layout }
);
562 // Tags used for encoding Spans:
563 pub const TAG_VALID_SPAN
: u8 = 0;
564 pub const TAG_INVALID_SPAN
: u8 = 1;
566 #[derive(RustcEncodable, RustcDecodable)]
567 pub struct EncodedExportedSymbols
{