]> git.proxmox.com Git - rustc.git/blame - src/librustc_metadata/schema.rs
New upstream version 1.26.2+dfsg1
[rustc.git] / src / librustc_metadata / schema.rs
CommitLineData
9e0c209e
SL
1// Copyright 2012-2016 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11use astencode;
12use index;
13
14use rustc::hir;
c30ab7b3 15use rustc::hir::def::{self, CtorKind};
7cac9316 16use rustc::hir::def_id::{DefIndex, DefId, CrateNum};
cc61c64b 17use rustc::ich::StableHashingContext;
0531ce1d
XL
18use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
19use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary, ForeignModule};
9e0c209e
SL
20use rustc::middle::lang_items;
21use rustc::mir;
abe05a73 22use rustc::session::CrateDisambiguator;
8bb4bdeb 23use rustc::ty::{self, Ty, ReprOptions};
c30ab7b3 24use rustc_back::PanicStrategy;
0531ce1d 25use rustc_back::target::TargetTriple;
9e0c209e
SL
26
27use rustc_serialize as serialize;
28use syntax::{ast, attr};
476ff2be 29use syntax::symbol::Symbol;
9e0c209e
SL
30use syntax_pos::{self, Span};
31
32use std::marker::PhantomData;
cc61c64b
XL
33use std::mem;
34
35use rustc_data_structures::stable_hasher::{StableHasher, HashStable,
36 StableHasherResult};
9e0c209e 37
c30ab7b3
SL
38pub fn rustc_version() -> String {
39 format!("rustc {}",
40 option_env!("CFG_VERSION").unwrap_or("unknown version"))
41}
9e0c209e
SL
42
43/// Metadata encoding version.
44/// NB: increment this if you change the format of metadata such that
476ff2be
SL
45/// the rustc version can't be found to compare with `rustc_version()`.
46pub const METADATA_VERSION: u8 = 4;
9e0c209e
SL
47
48/// Metadata header which includes `METADATA_VERSION`.
49/// To get older versions of rustc to ignore this metadata,
50/// there are 4 zero bytes at the start, which are treated
51/// as a length of 0 by old compilers.
52///
476ff2be
SL
53/// This header is followed by the position of the `CrateRoot`,
54/// which is encoded as a 32-bit big-endian unsigned integer,
55/// and further followed by the rustc version string.
c30ab7b3
SL
56pub const METADATA_HEADER: &'static [u8; 12] =
57 &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
9e0c209e 58
9e0c209e
SL
59/// A value of type T referred to by its absolute position
60/// in the metadata, and which can be decoded lazily.
61///
62/// Metadata is effective a tree, encoded in post-order,
63/// and with the root's position written next to the header.
64/// That means every single `Lazy` points to some previous
65/// location in the metadata and is part of a larger node.
66///
67/// The first `Lazy` in a node is encoded as the backwards
68/// distance from the position where the containing node
69/// starts and where the `Lazy` points to, while the rest
70/// use the forward distance from the previous `Lazy`.
71/// Distances start at 1, as 0-byte nodes are invalid.
72/// Also invalid are nodes being referred in a different
73/// order than they were encoded in.
74#[must_use]
75pub struct Lazy<T> {
76 pub position: usize,
c30ab7b3 77 _marker: PhantomData<T>,
9e0c209e
SL
78}
79
80impl<T> Lazy<T> {
81 pub fn with_position(position: usize) -> Lazy<T> {
82 Lazy {
3b2f2976 83 position,
c30ab7b3 84 _marker: PhantomData,
9e0c209e
SL
85 }
86 }
87
88 /// Returns the minimum encoded size of a value of type `T`.
89 // FIXME(eddyb) Give better estimates for certain types.
90 pub fn min_size() -> usize {
91 1
92 }
93}
94
95impl<T> Copy for Lazy<T> {}
96impl<T> Clone for Lazy<T> {
c30ab7b3
SL
97 fn clone(&self) -> Self {
98 *self
99 }
9e0c209e
SL
100}
101
102impl<T> serialize::UseSpecializedEncodable for Lazy<T> {}
103impl<T> serialize::UseSpecializedDecodable for Lazy<T> {}
104
cc61c64b
XL
105impl<CTX, T> HashStable<CTX> for Lazy<T> {
106 fn hash_stable<W: StableHasherResult>(&self,
107 _: &mut CTX,
108 _: &mut StableHasher<W>) {
109 // There's nothing to do. Whatever got encoded within this Lazy<>
110 // wrapper has already been hashed.
111 }
112}
113
9e0c209e
SL
114/// A sequence of type T referred to by its absolute position
115/// in the metadata and length, and which can be decoded lazily.
116/// The sequence is a single node for the purposes of `Lazy`.
117///
118/// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
119/// position, not at the position, which means that the length
120/// doesn't need to be known before encoding all the elements.
121///
122/// If the length is 0, no position is encoded, but otherwise,
123/// the encoding is that of `Lazy`, with the distinction that
124/// the minimal distance the length of the sequence, i.e.
125/// it's assumed there's no 0-byte element in the sequence.
126#[must_use]
127pub struct LazySeq<T> {
128 pub len: usize,
129 pub position: usize,
c30ab7b3 130 _marker: PhantomData<T>,
9e0c209e
SL
131}
132
133impl<T> LazySeq<T> {
134 pub fn empty() -> LazySeq<T> {
135 LazySeq::with_position_and_length(0, 0)
136 }
137
138 pub fn with_position_and_length(position: usize, len: usize) -> LazySeq<T> {
139 LazySeq {
3b2f2976
XL
140 len,
141 position,
c30ab7b3 142 _marker: PhantomData,
9e0c209e
SL
143 }
144 }
145
146 /// Returns the minimum encoded size of `length` values of type `T`.
147 pub fn min_size(length: usize) -> usize {
148 length
149 }
150}
151
152impl<T> Copy for LazySeq<T> {}
153impl<T> Clone for LazySeq<T> {
c30ab7b3
SL
154 fn clone(&self) -> Self {
155 *self
156 }
9e0c209e
SL
157}
158
159impl<T> serialize::UseSpecializedEncodable for LazySeq<T> {}
160impl<T> serialize::UseSpecializedDecodable for LazySeq<T> {}
161
cc61c64b
XL
162impl<CTX, T> HashStable<CTX> for LazySeq<T> {
163 fn hash_stable<W: StableHasherResult>(&self,
164 _: &mut CTX,
165 _: &mut StableHasher<W>) {
166 // There's nothing to do. Whatever got encoded within this Lazy<>
167 // wrapper has already been hashed.
168 }
169}
170
9e0c209e
SL
171/// Encoding / decoding state for `Lazy` and `LazySeq`.
172#[derive(Copy, Clone, PartialEq, Eq, Debug)]
173pub enum LazyState {
174 /// Outside of a metadata node.
175 NoNode,
176
177 /// Inside a metadata node, and before any `Lazy` or `LazySeq`.
178 /// The position is that of the node itself.
179 NodeStart(usize),
180
181 /// Inside a metadata node, with a previous `Lazy` or `LazySeq`.
182 /// The position is a conservative estimate of where that
183 /// previous `Lazy` / `LazySeq` would end (see their comments).
c30ab7b3 184 Previous(usize),
9e0c209e
SL
185}
186
187#[derive(RustcEncodable, RustcDecodable)]
188pub struct CrateRoot {
476ff2be 189 pub name: Symbol,
0531ce1d 190 pub triple: TargetTriple,
9e0c209e 191 pub hash: hir::svh::Svh,
abe05a73 192 pub disambiguator: CrateDisambiguator,
ea8adc8c
XL
193 pub panic_strategy: PanicStrategy,
194 pub has_global_allocator: bool,
195 pub has_default_lib_allocator: bool,
9e0c209e
SL
196 pub plugin_registrar_fn: Option<DefIndex>,
197 pub macro_derive_registrar: Option<DefIndex>,
198
ea8adc8c
XL
199 pub crate_deps: LazySeq<CrateDep>,
200 pub dylib_dependency_formats: LazySeq<Option<LinkagePreference>>,
201 pub lang_items: LazySeq<(DefIndex, usize)>,
202 pub lang_items_missing: LazySeq<lang_items::LangItem>,
203 pub native_libraries: LazySeq<NativeLibrary>,
0531ce1d 204 pub foreign_modules: LazySeq<ForeignModule>,
9e0c209e 205 pub codemap: LazySeq<syntax_pos::FileMap>,
32a655c1 206 pub def_path_table: Lazy<hir::map::definitions::DefPathTable>,
ea8adc8c 207 pub impls: LazySeq<TraitImpls>,
0531ce1d
XL
208 pub exported_symbols: LazySeq<(ExportedSymbol, SymbolExportLevel)>,
209 pub wasm_custom_sections: LazySeq<DefIndex>,
210 pub interpret_alloc_index: LazySeq<u32>,
211
9e0c209e
SL
212 pub index: LazySeq<index::Index>,
213}
214
215#[derive(RustcEncodable, RustcDecodable)]
216pub struct CrateDep {
217 pub name: ast::Name,
218 pub hash: hir::svh::Svh,
476ff2be 219 pub kind: DepKind,
9e0c209e
SL
220}
221
7cac9316
XL
222impl_stable_hash_for!(struct CrateDep {
223 name,
224 hash,
225 kind
226});
227
9e0c209e
SL
228#[derive(RustcEncodable, RustcDecodable)]
229pub struct TraitImpls {
230 pub trait_id: (u32, DefIndex),
c30ab7b3 231 pub impls: LazySeq<DefIndex>,
9e0c209e
SL
232}
233
0531ce1d 234impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TraitImpls {
7cac9316 235 fn hash_stable<W: StableHasherResult>(&self,
0531ce1d 236 hcx: &mut StableHashingContext<'a>,
7cac9316
XL
237 hasher: &mut StableHasher<W>) {
238 let TraitImpls {
239 trait_id: (krate, def_index),
240 ref impls,
241 } = *self;
242
243 DefId {
244 krate: CrateNum::from_u32(krate),
245 index: def_index
246 }.hash_stable(hcx, hasher);
247 impls.hash_stable(hcx, hasher);
248 }
249}
250
9e0c209e
SL
251#[derive(RustcEncodable, RustcDecodable)]
252pub struct Entry<'tcx> {
253 pub kind: EntryKind<'tcx>,
32a655c1 254 pub visibility: Lazy<ty::Visibility>,
476ff2be 255 pub span: Lazy<Span>,
9e0c209e
SL
256 pub attributes: LazySeq<ast::Attribute>,
257 pub children: LazySeq<DefIndex>,
258 pub stability: Option<Lazy<attr::Stability>>,
259 pub deprecation: Option<Lazy<attr::Deprecation>>,
260
261 pub ty: Option<Lazy<Ty<'tcx>>>,
262 pub inherent_impls: LazySeq<DefIndex>,
263 pub variances: LazySeq<ty::Variance>,
8bb4bdeb 264 pub generics: Option<Lazy<ty::Generics>>,
9e0c209e
SL
265 pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
266
267 pub ast: Option<Lazy<astencode::Ast<'tcx>>>,
c30ab7b3 268 pub mir: Option<Lazy<mir::Mir<'tcx>>>,
9e0c209e
SL
269}
270
cc61c64b
XL
271impl_stable_hash_for!(struct Entry<'tcx> {
272 kind,
273 visibility,
274 span,
275 attributes,
276 children,
277 stability,
278 deprecation,
279 ty,
280 inherent_impls,
281 variances,
282 generics,
283 predicates,
284 ast,
285 mir
286});
287
9e0c209e
SL
288#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
289pub enum EntryKind<'tcx> {
8bb4bdeb 290 Const(u8),
9e0c209e
SL
291 ImmStatic,
292 MutStatic,
293 ForeignImmStatic,
294 ForeignMutStatic,
295 ForeignMod,
abe05a73 296 ForeignType,
cc61c64b 297 GlobalAsm,
9e0c209e 298 Type,
8bb4bdeb 299 Enum(ReprOptions),
9e0c209e 300 Field,
041b39d2
XL
301 Variant(Lazy<VariantData<'tcx>>),
302 Struct(Lazy<VariantData<'tcx>>, ReprOptions),
303 Union(Lazy<VariantData<'tcx>>, ReprOptions),
304 Fn(Lazy<FnData<'tcx>>),
305 ForeignFn(Lazy<FnData<'tcx>>),
9e0c209e 306 Mod(Lazy<ModData>),
476ff2be 307 MacroDef(Lazy<MacroDef>),
9e0c209e 308 Closure(Lazy<ClosureData<'tcx>>),
ea8adc8c 309 Generator(Lazy<GeneratorData<'tcx>>),
9e0c209e
SL
310 Trait(Lazy<TraitData<'tcx>>),
311 Impl(Lazy<ImplData<'tcx>>),
041b39d2 312 Method(Lazy<MethodData<'tcx>>),
9e0c209e 313 AssociatedType(AssociatedContainer),
8bb4bdeb 314 AssociatedConst(AssociatedContainer, u8),
32a655c1
SL
315}
316
0531ce1d 317impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for EntryKind<'gcx> {
cc61c64b 318 fn hash_stable<W: StableHasherResult>(&self,
0531ce1d 319 hcx: &mut StableHashingContext<'a>,
cc61c64b
XL
320 hasher: &mut StableHasher<W>) {
321 mem::discriminant(self).hash_stable(hcx, hasher);
322 match *self {
323 EntryKind::ImmStatic |
324 EntryKind::MutStatic |
325 EntryKind::ForeignImmStatic |
326 EntryKind::ForeignMutStatic |
327 EntryKind::ForeignMod |
328 EntryKind::GlobalAsm |
abe05a73 329 EntryKind::ForeignType |
cc61c64b
XL
330 EntryKind::Field |
331 EntryKind::Type => {
332 // Nothing else to hash here.
333 }
334 EntryKind::Const(qualif) => {
335 qualif.hash_stable(hcx, hasher);
336 }
337 EntryKind::Enum(ref repr_options) => {
338 repr_options.hash_stable(hcx, hasher);
339 }
340 EntryKind::Variant(ref variant_data) => {
341 variant_data.hash_stable(hcx, hasher);
342 }
343 EntryKind::Struct(ref variant_data, ref repr_options) |
344 EntryKind::Union(ref variant_data, ref repr_options) => {
345 variant_data.hash_stable(hcx, hasher);
346 repr_options.hash_stable(hcx, hasher);
347 }
348 EntryKind::Fn(ref fn_data) |
349 EntryKind::ForeignFn(ref fn_data) => {
350 fn_data.hash_stable(hcx, hasher);
351 }
352 EntryKind::Mod(ref mod_data) => {
353 mod_data.hash_stable(hcx, hasher);
354 }
355 EntryKind::MacroDef(ref macro_def) => {
356 macro_def.hash_stable(hcx, hasher);
357 }
ea8adc8c
XL
358 EntryKind::Generator(data) => {
359 data.hash_stable(hcx, hasher);
360 }
cc61c64b
XL
361 EntryKind::Closure(closure_data) => {
362 closure_data.hash_stable(hcx, hasher);
363 }
364 EntryKind::Trait(ref trait_data) => {
365 trait_data.hash_stable(hcx, hasher);
366 }
cc61c64b
XL
367 EntryKind::Impl(ref impl_data) => {
368 impl_data.hash_stable(hcx, hasher);
369 }
370 EntryKind::Method(ref method_data) => {
371 method_data.hash_stable(hcx, hasher);
372 }
373 EntryKind::AssociatedType(associated_container) => {
374 associated_container.hash_stable(hcx, hasher);
375 }
376 EntryKind::AssociatedConst(associated_container, qualif) => {
377 associated_container.hash_stable(hcx, hasher);
378 qualif.hash_stable(hcx, hasher);
379 }
380 }
381 }
382}
383
9e0c209e
SL
384#[derive(RustcEncodable, RustcDecodable)]
385pub struct ModData {
c30ab7b3 386 pub reexports: LazySeq<def::Export>,
9e0c209e
SL
387}
388
cc61c64b
XL
389impl_stable_hash_for!(struct ModData { reexports });
390
476ff2be
SL
391#[derive(RustcEncodable, RustcDecodable)]
392pub struct MacroDef {
393 pub body: String,
7cac9316 394 pub legacy: bool,
476ff2be
SL
395}
396
7cac9316 397impl_stable_hash_for!(struct MacroDef { body, legacy });
cc61c64b 398
9e0c209e 399#[derive(RustcEncodable, RustcDecodable)]
041b39d2 400pub struct FnData<'tcx> {
9e0c209e 401 pub constness: hir::Constness,
c30ab7b3 402 pub arg_names: LazySeq<ast::Name>,
041b39d2 403 pub sig: Lazy<ty::PolyFnSig<'tcx>>,
9e0c209e
SL
404}
405
041b39d2 406impl_stable_hash_for!(struct FnData<'tcx> { constness, arg_names, sig });
cc61c64b 407
9e0c209e 408#[derive(RustcEncodable, RustcDecodable)]
041b39d2 409pub struct VariantData<'tcx> {
c30ab7b3 410 pub ctor_kind: CtorKind,
8bb4bdeb 411 pub discr: ty::VariantDiscr,
9e0c209e
SL
412
413 /// If this is a struct's only variant, this
414 /// is the index of the "struct ctor" item.
c30ab7b3 415 pub struct_ctor: Option<DefIndex>,
041b39d2
XL
416
417 /// If this is a tuple struct or variant
418 /// ctor, this is its "function" signature.
419 pub ctor_sig: Option<Lazy<ty::PolyFnSig<'tcx>>>,
9e0c209e
SL
420}
421
041b39d2 422impl_stable_hash_for!(struct VariantData<'tcx> {
cc61c64b
XL
423 ctor_kind,
424 discr,
041b39d2
XL
425 struct_ctor,
426 ctor_sig
cc61c64b
XL
427});
428
9e0c209e
SL
429#[derive(RustcEncodable, RustcDecodable)]
430pub struct TraitData<'tcx> {
431 pub unsafety: hir::Unsafety,
432 pub paren_sugar: bool,
abe05a73 433 pub has_auto_impl: bool,
c30ab7b3 434 pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
9e0c209e
SL
435}
436
cc61c64b
XL
437impl_stable_hash_for!(struct TraitData<'tcx> {
438 unsafety,
439 paren_sugar,
abe05a73 440 has_auto_impl,
cc61c64b
XL
441 super_predicates
442});
443
9e0c209e
SL
444#[derive(RustcEncodable, RustcDecodable)]
445pub struct ImplData<'tcx> {
446 pub polarity: hir::ImplPolarity,
7cac9316 447 pub defaultness: hir::Defaultness,
9e0c209e 448 pub parent_impl: Option<DefId>,
cc61c64b
XL
449
450 /// This is `Some` only for impls of `CoerceUnsized`.
451 pub coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
c30ab7b3 452 pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>,
9e0c209e
SL
453}
454
cc61c64b
XL
455impl_stable_hash_for!(struct ImplData<'tcx> {
456 polarity,
7cac9316 457 defaultness,
cc61c64b
XL
458 parent_impl,
459 coerce_unsized_info,
460 trait_ref
461});
462
463
9e0c209e
SL
464/// Describes whether the container of an associated item
465/// is a trait or an impl and whether, in a trait, it has
466/// a default, or an in impl, whether it's marked "default".
467#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
468pub enum AssociatedContainer {
469 TraitRequired,
470 TraitWithDefault,
471 ImplDefault,
c30ab7b3 472 ImplFinal,
9e0c209e
SL
473}
474
cc61c64b
XL
475impl_stable_hash_for!(enum ::schema::AssociatedContainer {
476 TraitRequired,
477 TraitWithDefault,
478 ImplDefault,
479 ImplFinal
480});
481
9e0c209e 482impl AssociatedContainer {
476ff2be 483 pub fn with_def_id(&self, def_id: DefId) -> ty::AssociatedItemContainer {
9e0c209e
SL
484 match *self {
485 AssociatedContainer::TraitRequired |
c30ab7b3 486 AssociatedContainer::TraitWithDefault => ty::TraitContainer(def_id),
9e0c209e
SL
487
488 AssociatedContainer::ImplDefault |
c30ab7b3 489 AssociatedContainer::ImplFinal => ty::ImplContainer(def_id),
9e0c209e
SL
490 }
491 }
492
9e0c209e
SL
493 pub fn defaultness(&self) -> hir::Defaultness {
494 match *self {
476ff2be
SL
495 AssociatedContainer::TraitRequired => hir::Defaultness::Default {
496 has_value: false,
497 },
498
9e0c209e 499 AssociatedContainer::TraitWithDefault |
476ff2be
SL
500 AssociatedContainer::ImplDefault => hir::Defaultness::Default {
501 has_value: true,
502 },
9e0c209e 503
c30ab7b3 504 AssociatedContainer::ImplFinal => hir::Defaultness::Final,
9e0c209e
SL
505 }
506 }
507}
508
509#[derive(RustcEncodable, RustcDecodable)]
041b39d2
XL
510pub struct MethodData<'tcx> {
511 pub fn_data: FnData<'tcx>,
9e0c209e 512 pub container: AssociatedContainer,
476ff2be 513 pub has_self: bool,
9e0c209e 514}
041b39d2 515impl_stable_hash_for!(struct MethodData<'tcx> { fn_data, container, has_self });
9e0c209e
SL
516
517#[derive(RustcEncodable, RustcDecodable)]
518pub struct ClosureData<'tcx> {
041b39d2 519 pub sig: Lazy<ty::PolyFnSig<'tcx>>,
9e0c209e 520}
ff7c6d11 521impl_stable_hash_for!(struct ClosureData<'tcx> { sig });
ea8adc8c
XL
522
523#[derive(RustcEncodable, RustcDecodable)]
524pub struct GeneratorData<'tcx> {
ea8adc8c
XL
525 pub layout: mir::GeneratorLayout<'tcx>,
526}
ff7c6d11 527impl_stable_hash_for!(struct GeneratorData<'tcx> { layout });
2c00a5a8
XL
528
529// Tags used for encoding Spans:
530pub const TAG_VALID_SPAN: u8 = 0;
531pub const TAG_INVALID_SPAN: u8 = 1;