]>
Commit | Line | Data |
---|---|---|
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 | ||
11 | use astencode; | |
12 | use index; | |
13 | ||
14 | use rustc::hir; | |
c30ab7b3 | 15 | use rustc::hir::def::{self, CtorKind}; |
9e0c209e | 16 | use rustc::hir::def_id::{DefIndex, DefId}; |
476ff2be | 17 | use rustc::middle::cstore::{DepKind, LinkagePreference, NativeLibrary}; |
9e0c209e SL |
18 | use rustc::middle::lang_items; |
19 | use rustc::mir; | |
20 | use rustc::ty::{self, Ty}; | |
c30ab7b3 | 21 | use rustc_back::PanicStrategy; |
9e0c209e SL |
22 | |
23 | use rustc_serialize as serialize; | |
24 | use syntax::{ast, attr}; | |
476ff2be | 25 | use syntax::symbol::Symbol; |
9e0c209e SL |
26 | use syntax_pos::{self, Span}; |
27 | ||
28 | use std::marker::PhantomData; | |
29 | ||
c30ab7b3 SL |
30 | pub 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()`. |
38 | pub 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 |
48 | pub 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. | |
54 | pub 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] | |
72 | pub struct Lazy<T> { | |
73 | pub position: usize, | |
c30ab7b3 | 74 | _marker: PhantomData<T>, |
9e0c209e SL |
75 | } |
76 | ||
77 | impl<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 | ||
92 | impl<T> Copy for Lazy<T> {} | |
93 | impl<T> Clone for Lazy<T> { | |
c30ab7b3 SL |
94 | fn clone(&self) -> Self { |
95 | *self | |
96 | } | |
9e0c209e SL |
97 | } |
98 | ||
99 | impl<T> serialize::UseSpecializedEncodable for Lazy<T> {} | |
100 | impl<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] | |
115 | pub struct LazySeq<T> { | |
116 | pub len: usize, | |
117 | pub position: usize, | |
c30ab7b3 | 118 | _marker: PhantomData<T>, |
9e0c209e SL |
119 | } |
120 | ||
121 | impl<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 | ||
140 | impl<T> Copy for LazySeq<T> {} | |
141 | impl<T> Clone for LazySeq<T> { | |
c30ab7b3 SL |
142 | fn clone(&self) -> Self { |
143 | *self | |
144 | } | |
9e0c209e SL |
145 | } |
146 | ||
147 | impl<T> serialize::UseSpecializedEncodable for LazySeq<T> {} | |
148 | impl<T> serialize::UseSpecializedDecodable for LazySeq<T> {} | |
149 | ||
150 | /// Encoding / decoding state for `Lazy` and `LazySeq`. | |
151 | #[derive(Copy, Clone, PartialEq, Eq, Debug)] | |
152 | pub 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)] | |
167 | pub 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)] | |
188 | pub 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)] | |
195 | pub struct TraitImpls { | |
196 | pub trait_id: (u32, DefIndex), | |
c30ab7b3 | 197 | pub impls: LazySeq<DefIndex>, |
9e0c209e SL |
198 | } |
199 | ||
9e0c209e SL |
200 | #[derive(RustcEncodable, RustcDecodable)] |
201 | pub 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)] | |
222 | pub 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)] | |
249 | pub struct ModData { | |
c30ab7b3 | 250 | pub reexports: LazySeq<def::Export>, |
9e0c209e SL |
251 | } |
252 | ||
476ff2be SL |
253 | #[derive(RustcEncodable, RustcDecodable)] |
254 | pub struct MacroDef { | |
255 | pub body: String, | |
256 | } | |
257 | ||
9e0c209e SL |
258 | #[derive(RustcEncodable, RustcDecodable)] |
259 | pub struct FnData { | |
260 | pub constness: hir::Constness, | |
c30ab7b3 | 261 | pub arg_names: LazySeq<ast::Name>, |
9e0c209e SL |
262 | } |
263 | ||
264 | #[derive(RustcEncodable, RustcDecodable)] | |
265 | pub 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)] | |
275 | pub 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)] | |
283 | pub 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)] | |
294 | pub enum AssociatedContainer { | |
295 | TraitRequired, | |
296 | TraitWithDefault, | |
297 | ImplDefault, | |
c30ab7b3 | 298 | ImplFinal, |
9e0c209e SL |
299 | } |
300 | ||
301 | impl 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 | 329 | pub 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)] | |
336 | pub struct ClosureData<'tcx> { | |
337 | pub kind: ty::ClosureKind, | |
c30ab7b3 | 338 | pub ty: Lazy<ty::ClosureTy<'tcx>>, |
9e0c209e | 339 | } |