]> git.proxmox.com Git - rustc.git/blame - src/librustc_metadata/schema.rs
New upstream version 1.15.1+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};
9e0c209e 16use rustc::hir::def_id::{DefIndex, DefId};
476ff2be 17use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary};
9e0c209e
SL
18use rustc::middle::lang_items;
19use rustc::mir;
20use rustc::ty::{self, Ty};
c30ab7b3 21use rustc_back::PanicStrategy;
9e0c209e
SL
22
23use rustc_serialize as serialize;
24use syntax::{ast, attr};
476ff2be 25use syntax::symbol::Symbol;
9e0c209e
SL
26use syntax_pos::{self, Span};
27
28use std::marker::PhantomData;
29
c30ab7b3
SL
30pub fn rustc_version() -> String {
31 format!("rustc {}",
32 option_env!("CFG_VERSION").unwrap_or("unknown version"))
33}
9e0c209e
SL
34
35/// Metadata encoding version.
36/// NB: increment this if you change the format of metadata such that
476ff2be
SL
37/// the rustc version can't be found to compare with `rustc_version()`.
38pub const METADATA_VERSION: u8 = 4;
9e0c209e
SL
39
40/// Metadata header which includes `METADATA_VERSION`.
41/// To get older versions of rustc to ignore this metadata,
42/// there are 4 zero bytes at the start, which are treated
43/// as a length of 0 by old compilers.
44///
476ff2be
SL
45/// This header is followed by the position of the `CrateRoot`,
46/// which is encoded as a 32-bit big-endian unsigned integer,
47/// and further followed by the rustc version string.
c30ab7b3
SL
48pub const METADATA_HEADER: &'static [u8; 12] =
49 &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
9e0c209e
SL
50
51/// The shorthand encoding uses an enum's variant index `usize`
52/// and is offset by this value so it never matches a real variant.
53/// This offset is also chosen so that the first byte is never < 0x80.
54pub const SHORTHAND_OFFSET: usize = 0x80;
55
56/// A value of type T referred to by its absolute position
57/// in the metadata, and which can be decoded lazily.
58///
59/// Metadata is effective a tree, encoded in post-order,
60/// and with the root's position written next to the header.
61/// That means every single `Lazy` points to some previous
62/// location in the metadata and is part of a larger node.
63///
64/// The first `Lazy` in a node is encoded as the backwards
65/// distance from the position where the containing node
66/// starts and where the `Lazy` points to, while the rest
67/// use the forward distance from the previous `Lazy`.
68/// Distances start at 1, as 0-byte nodes are invalid.
69/// Also invalid are nodes being referred in a different
70/// order than they were encoded in.
71#[must_use]
72pub struct Lazy<T> {
73 pub position: usize,
c30ab7b3 74 _marker: PhantomData<T>,
9e0c209e
SL
75}
76
77impl<T> Lazy<T> {
78 pub fn with_position(position: usize) -> Lazy<T> {
79 Lazy {
80 position: position,
c30ab7b3 81 _marker: PhantomData,
9e0c209e
SL
82 }
83 }
84
85 /// Returns the minimum encoded size of a value of type `T`.
86 // FIXME(eddyb) Give better estimates for certain types.
87 pub fn min_size() -> usize {
88 1
89 }
90}
91
92impl<T> Copy for Lazy<T> {}
93impl<T> Clone for Lazy<T> {
c30ab7b3
SL
94 fn clone(&self) -> Self {
95 *self
96 }
9e0c209e
SL
97}
98
99impl<T> serialize::UseSpecializedEncodable for Lazy<T> {}
100impl<T> serialize::UseSpecializedDecodable for Lazy<T> {}
101
102/// A sequence of type T referred to by its absolute position
103/// in the metadata and length, and which can be decoded lazily.
104/// The sequence is a single node for the purposes of `Lazy`.
105///
106/// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
107/// position, not at the position, which means that the length
108/// doesn't need to be known before encoding all the elements.
109///
110/// If the length is 0, no position is encoded, but otherwise,
111/// the encoding is that of `Lazy`, with the distinction that
112/// the minimal distance the length of the sequence, i.e.
113/// it's assumed there's no 0-byte element in the sequence.
114#[must_use]
115pub struct LazySeq<T> {
116 pub len: usize,
117 pub position: usize,
c30ab7b3 118 _marker: PhantomData<T>,
9e0c209e
SL
119}
120
121impl<T> LazySeq<T> {
122 pub fn empty() -> LazySeq<T> {
123 LazySeq::with_position_and_length(0, 0)
124 }
125
126 pub fn with_position_and_length(position: usize, len: usize) -> LazySeq<T> {
127 LazySeq {
128 len: len,
129 position: position,
c30ab7b3 130 _marker: PhantomData,
9e0c209e
SL
131 }
132 }
133
134 /// Returns the minimum encoded size of `length` values of type `T`.
135 pub fn min_size(length: usize) -> usize {
136 length
137 }
138}
139
140impl<T> Copy for LazySeq<T> {}
141impl<T> Clone for LazySeq<T> {
c30ab7b3
SL
142 fn clone(&self) -> Self {
143 *self
144 }
9e0c209e
SL
145}
146
147impl<T> serialize::UseSpecializedEncodable for LazySeq<T> {}
148impl<T> serialize::UseSpecializedDecodable for LazySeq<T> {}
149
150/// Encoding / decoding state for `Lazy` and `LazySeq`.
151#[derive(Copy, Clone, PartialEq, Eq, Debug)]
152pub enum LazyState {
153 /// Outside of a metadata node.
154 NoNode,
155
156 /// Inside a metadata node, and before any `Lazy` or `LazySeq`.
157 /// The position is that of the node itself.
158 NodeStart(usize),
159
160 /// Inside a metadata node, with a previous `Lazy` or `LazySeq`.
161 /// The position is a conservative estimate of where that
162 /// previous `Lazy` / `LazySeq` would end (see their comments).
c30ab7b3 163 Previous(usize),
9e0c209e
SL
164}
165
166#[derive(RustcEncodable, RustcDecodable)]
167pub struct CrateRoot {
476ff2be 168 pub name: Symbol,
9e0c209e
SL
169 pub triple: String,
170 pub hash: hir::svh::Svh,
476ff2be 171 pub disambiguator: Symbol,
9e0c209e
SL
172 pub panic_strategy: PanicStrategy,
173 pub plugin_registrar_fn: Option<DefIndex>,
174 pub macro_derive_registrar: Option<DefIndex>,
175
176 pub crate_deps: LazySeq<CrateDep>,
177 pub dylib_dependency_formats: LazySeq<Option<LinkagePreference>>,
178 pub lang_items: LazySeq<(DefIndex, usize)>,
179 pub lang_items_missing: LazySeq<lang_items::LangItem>,
476ff2be 180 pub native_libraries: LazySeq<NativeLibrary>,
9e0c209e 181 pub codemap: LazySeq<syntax_pos::FileMap>,
9e0c209e 182 pub impls: LazySeq<TraitImpls>,
476ff2be 183 pub exported_symbols: LazySeq<DefIndex>,
9e0c209e
SL
184 pub index: LazySeq<index::Index>,
185}
186
187#[derive(RustcEncodable, RustcDecodable)]
188pub struct CrateDep {
189 pub name: ast::Name,
190 pub hash: hir::svh::Svh,
476ff2be 191 pub kind: DepKind,
9e0c209e
SL
192}
193
194#[derive(RustcEncodable, RustcDecodable)]
195pub struct TraitImpls {
196 pub trait_id: (u32, DefIndex),
c30ab7b3 197 pub impls: LazySeq<DefIndex>,
9e0c209e
SL
198}
199
9e0c209e
SL
200#[derive(RustcEncodable, RustcDecodable)]
201pub struct Entry<'tcx> {
202 pub kind: EntryKind<'tcx>,
203 pub visibility: ty::Visibility,
476ff2be 204 pub span: Lazy<Span>,
9e0c209e
SL
205 pub def_key: Lazy<hir::map::DefKey>,
206 pub attributes: LazySeq<ast::Attribute>,
207 pub children: LazySeq<DefIndex>,
208 pub stability: Option<Lazy<attr::Stability>>,
209 pub deprecation: Option<Lazy<attr::Deprecation>>,
210
211 pub ty: Option<Lazy<Ty<'tcx>>>,
212 pub inherent_impls: LazySeq<DefIndex>,
213 pub variances: LazySeq<ty::Variance>,
214 pub generics: Option<Lazy<ty::Generics<'tcx>>>,
215 pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
216
217 pub ast: Option<Lazy<astencode::Ast<'tcx>>>,
c30ab7b3 218 pub mir: Option<Lazy<mir::Mir<'tcx>>>,
9e0c209e
SL
219}
220
221#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
222pub enum EntryKind<'tcx> {
223 Const,
224 ImmStatic,
225 MutStatic,
226 ForeignImmStatic,
227 ForeignMutStatic,
228 ForeignMod,
229 Type,
230 Enum,
231 Field,
232 Variant(Lazy<VariantData>),
233 Struct(Lazy<VariantData>),
234 Union(Lazy<VariantData>),
235 Fn(Lazy<FnData>),
236 ForeignFn(Lazy<FnData>),
237 Mod(Lazy<ModData>),
476ff2be 238 MacroDef(Lazy<MacroDef>),
9e0c209e
SL
239 Closure(Lazy<ClosureData<'tcx>>),
240 Trait(Lazy<TraitData<'tcx>>),
241 Impl(Lazy<ImplData<'tcx>>),
242 DefaultImpl(Lazy<ImplData<'tcx>>),
476ff2be 243 Method(Lazy<MethodData>),
9e0c209e 244 AssociatedType(AssociatedContainer),
c30ab7b3 245 AssociatedConst(AssociatedContainer),
9e0c209e
SL
246}
247
248#[derive(RustcEncodable, RustcDecodable)]
249pub struct ModData {
c30ab7b3 250 pub reexports: LazySeq<def::Export>,
9e0c209e
SL
251}
252
476ff2be
SL
253#[derive(RustcEncodable, RustcDecodable)]
254pub struct MacroDef {
255 pub body: String,
256}
257
9e0c209e
SL
258#[derive(RustcEncodable, RustcDecodable)]
259pub struct FnData {
260 pub constness: hir::Constness,
c30ab7b3 261 pub arg_names: LazySeq<ast::Name>,
9e0c209e
SL
262}
263
264#[derive(RustcEncodable, RustcDecodable)]
265pub struct VariantData {
c30ab7b3 266 pub ctor_kind: CtorKind,
9e0c209e
SL
267 pub disr: u64,
268
269 /// If this is a struct's only variant, this
270 /// is the index of the "struct ctor" item.
c30ab7b3 271 pub struct_ctor: Option<DefIndex>,
9e0c209e
SL
272}
273
274#[derive(RustcEncodable, RustcDecodable)]
275pub struct TraitData<'tcx> {
276 pub unsafety: hir::Unsafety,
277 pub paren_sugar: bool,
278 pub has_default_impl: bool,
c30ab7b3 279 pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
9e0c209e
SL
280}
281
282#[derive(RustcEncodable, RustcDecodable)]
283pub struct ImplData<'tcx> {
284 pub polarity: hir::ImplPolarity,
285 pub parent_impl: Option<DefId>,
286 pub coerce_unsized_kind: Option<ty::adjustment::CustomCoerceUnsized>,
c30ab7b3 287 pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>,
9e0c209e
SL
288}
289
290/// Describes whether the container of an associated item
291/// is a trait or an impl and whether, in a trait, it has
292/// a default, or an in impl, whether it's marked "default".
293#[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
294pub enum AssociatedContainer {
295 TraitRequired,
296 TraitWithDefault,
297 ImplDefault,
c30ab7b3 298 ImplFinal,
9e0c209e
SL
299}
300
301impl AssociatedContainer {
476ff2be 302 pub fn with_def_id(&self, def_id: DefId) -> ty::AssociatedItemContainer {
9e0c209e
SL
303 match *self {
304 AssociatedContainer::TraitRequired |
c30ab7b3 305 AssociatedContainer::TraitWithDefault => ty::TraitContainer(def_id),
9e0c209e
SL
306
307 AssociatedContainer::ImplDefault |
c30ab7b3 308 AssociatedContainer::ImplFinal => ty::ImplContainer(def_id),
9e0c209e
SL
309 }
310 }
311
9e0c209e
SL
312 pub fn defaultness(&self) -> hir::Defaultness {
313 match *self {
476ff2be
SL
314 AssociatedContainer::TraitRequired => hir::Defaultness::Default {
315 has_value: false,
316 },
317
9e0c209e 318 AssociatedContainer::TraitWithDefault |
476ff2be
SL
319 AssociatedContainer::ImplDefault => hir::Defaultness::Default {
320 has_value: true,
321 },
9e0c209e 322
c30ab7b3 323 AssociatedContainer::ImplFinal => hir::Defaultness::Final,
9e0c209e
SL
324 }
325 }
326}
327
328#[derive(RustcEncodable, RustcDecodable)]
476ff2be 329pub struct MethodData {
9e0c209e
SL
330 pub fn_data: FnData,
331 pub container: AssociatedContainer,
476ff2be 332 pub has_self: bool,
9e0c209e
SL
333}
334
335#[derive(RustcEncodable, RustcDecodable)]
336pub struct ClosureData<'tcx> {
337 pub kind: ty::ClosureKind,
c30ab7b3 338 pub ty: Lazy<ty::ClosureTy<'tcx>>,
9e0c209e 339}