]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_metadata/src/rmeta/mod.rs
6353e04316b1a03a2f47cc4909061e007edf31b9
[rust.git] / compiler / rustc_metadata / src / rmeta / mod.rs
1 use crate::creader::CrateMetadataRef;
2 use decoder::Metadata;
3 use def_path_hash_map::DefPathHashMapRef;
4 use table::TableBuilder;
5
6 use rustc_ast as ast;
7 use rustc_attr as attr;
8 use rustc_data_structures::svh::Svh;
9 use rustc_data_structures::sync::MetadataRef;
10 use rustc_hir as hir;
11 use rustc_hir::def::{CtorKind, DefKind};
12 use rustc_hir::def_id::{CrateNum, DefId, DefIndex, DefPathHash, StableCrateId};
13 use rustc_hir::definitions::DefKey;
14 use rustc_hir::lang_items;
15 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
16 use rustc_middle::metadata::ModChild;
17 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
18 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
19 use rustc_middle::middle::resolve_lifetime::ObjectLifetimeDefault;
20 use rustc_middle::mir;
21 use rustc_middle::ty::fast_reject::SimplifiedType;
22 use rustc_middle::ty::query::Providers;
23 use rustc_middle::ty::{self, ReprOptions, Ty};
24 use rustc_middle::ty::{GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
25 use rustc_serialize::opaque::FileEncoder;
26 use rustc_session::config::SymbolManglingVersion;
27 use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
28 use rustc_span::edition::Edition;
29 use rustc_span::hygiene::{ExpnIndex, MacroKind};
30 use rustc_span::symbol::{Ident, Symbol};
31 use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
32 use rustc_target::spec::{PanicStrategy, TargetTriple};
33
34 use std::marker::PhantomData;
35 use std::num::NonZeroUsize;
36
37 pub use decoder::provide_extern;
38 use decoder::DecodeContext;
39 pub(crate) use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
40 use encoder::EncodeContext;
41 pub use encoder::{encode_metadata, EncodedMetadata};
42 use rustc_span::hygiene::SyntaxContextData;
43
44 mod decoder;
45 mod def_path_hash_map;
46 mod encoder;
47 mod table;
48
49 pub(crate) fn rustc_version() -> String {
50     format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version"))
51 }
52
53 /// Metadata encoding version.
54 /// N.B., increment this if you change the format of metadata such that
55 /// the rustc version can't be found to compare with `rustc_version()`.
56 const METADATA_VERSION: u8 = 6;
57
58 /// Metadata header which includes `METADATA_VERSION`.
59 ///
60 /// This header is followed by the position of the `CrateRoot`,
61 /// which is encoded as a 32-bit big-endian unsigned integer,
62 /// and further followed by the rustc version string.
63 pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
64
65 /// A value of type T referred to by its absolute position
66 /// in the metadata, and which can be decoded lazily.
67 ///
68 /// Metadata is effective a tree, encoded in post-order,
69 /// and with the root's position written next to the header.
70 /// That means every single `LazyValue` points to some previous
71 /// location in the metadata and is part of a larger node.
72 ///
73 /// The first `LazyValue` in a node is encoded as the backwards
74 /// distance from the position where the containing node
75 /// starts and where the `LazyValue` points to, while the rest
76 /// use the forward distance from the previous `LazyValue`.
77 /// Distances start at 1, as 0-byte nodes are invalid.
78 /// Also invalid are nodes being referred in a different
79 /// order than they were encoded in.
80 #[must_use]
81 struct LazyValue<T> {
82     position: NonZeroUsize,
83     _marker: PhantomData<fn() -> T>,
84 }
85
86 impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyValue<T> {
87     type Value<'tcx> = LazyValue<T::Value<'tcx>>;
88 }
89
90 impl<T> LazyValue<T> {
91     fn from_position(position: NonZeroUsize) -> LazyValue<T> {
92         LazyValue { position, _marker: PhantomData }
93     }
94 }
95
96 /// A list of lazily-decoded values.
97 ///
98 /// Unlike `LazyValue<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.
101 ///
102 /// If the length is 0, no position is encoded, but otherwise,
103 /// the encoding is that of `LazyArray`, 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.
106 struct LazyArray<T> {
107     position: NonZeroUsize,
108     num_elems: usize,
109     _marker: PhantomData<fn() -> T>,
110 }
111
112 impl<T: ParameterizedOverTcx> ParameterizedOverTcx for LazyArray<T> {
113     type Value<'tcx> = LazyArray<T::Value<'tcx>>;
114 }
115
116 impl<T> LazyArray<T> {
117     fn from_position_and_num_elems(position: NonZeroUsize, num_elems: usize) -> LazyArray<T> {
118         LazyArray { position, num_elems, _marker: PhantomData }
119     }
120
121     fn empty() -> LazyArray<T> {
122         LazyArray::from_position_and_num_elems(NonZeroUsize::new(1).unwrap(), 0)
123     }
124 }
125
126 /// A list of lazily-decoded values, with the added capability of random access.
127 ///
128 /// Random-access table (i.e. offering constant-time `get`/`set`), similar to
129 /// `LazyArray<T>`, but without requiring encoding or decoding all the values
130 /// eagerly and in-order.
131 struct LazyTable<I, T> {
132     position: NonZeroUsize,
133     encoded_size: usize,
134     _marker: PhantomData<fn(I) -> T>,
135 }
136
137 impl<I: 'static, T: ParameterizedOverTcx> ParameterizedOverTcx for LazyTable<I, T> {
138     type Value<'tcx> = LazyTable<I, T::Value<'tcx>>;
139 }
140
141 impl<I, T> LazyTable<I, T> {
142     fn from_position_and_encoded_size(
143         position: NonZeroUsize,
144         encoded_size: usize,
145     ) -> LazyTable<I, T> {
146         LazyTable { position, encoded_size, _marker: PhantomData }
147     }
148 }
149
150 impl<T> Copy for LazyValue<T> {}
151 impl<T> Clone for LazyValue<T> {
152     fn clone(&self) -> Self {
153         *self
154     }
155 }
156
157 impl<T> Copy for LazyArray<T> {}
158 impl<T> Clone for LazyArray<T> {
159     fn clone(&self) -> Self {
160         *self
161     }
162 }
163
164 impl<I, T> Copy for LazyTable<I, T> {}
165 impl<I, T> Clone for LazyTable<I, T> {
166     fn clone(&self) -> Self {
167         *self
168     }
169 }
170
171 /// Encoding / decoding state for `Lazy`s (`LazyValue`, `LazyArray`, and `LazyTable`).
172 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
173 enum LazyState {
174     /// Outside of a metadata node.
175     NoNode,
176
177     /// Inside a metadata node, and before any `Lazy`s.
178     /// The position is that of the node itself.
179     NodeStart(NonZeroUsize),
180
181     /// Inside a metadata node, with a previous `Lazy`s.
182     /// The position is where that previous `Lazy` would start.
183     Previous(NonZeroUsize),
184 }
185
186 type SyntaxContextTable = LazyTable<u32, LazyValue<SyntaxContextData>>;
187 type ExpnDataTable = LazyTable<ExpnIndex, LazyValue<ExpnData>>;
188 type ExpnHashTable = LazyTable<ExpnIndex, LazyValue<ExpnHash>>;
189
190 #[derive(MetadataEncodable, MetadataDecodable)]
191 pub(crate) struct ProcMacroData {
192     proc_macro_decls_static: DefIndex,
193     stability: Option<attr::Stability>,
194     macros: LazyArray<DefIndex>,
195 }
196
197 /// Serialized metadata for a crate.
198 /// When compiling a proc-macro crate, we encode many of
199 /// the `LazyArray<T>` fields as `Lazy::empty()`. This serves two purposes:
200 ///
201 /// 1. We avoid performing unnecessary work. Proc-macro crates can only
202 /// export proc-macros functions, which are compiled into a shared library.
203 /// As a result, a large amount of the information we normally store
204 /// (e.g. optimized MIR) is unneeded by downstream crates.
205 /// 2. We avoid serializing invalid `CrateNum`s. When we deserialize
206 /// a proc-macro crate, we don't load any of its dependencies (since we
207 /// just need to invoke a native function from the shared library).
208 /// This means that any foreign `CrateNum`s that we serialize cannot be
209 /// deserialized, since we will not know how to map them into the current
210 /// compilation session. If we were to serialize a proc-macro crate like
211 /// a normal crate, much of what we serialized would be unusable in addition
212 /// to being unused.
213 #[derive(MetadataEncodable, MetadataDecodable)]
214 pub(crate) struct CrateRoot {
215     name: Symbol,
216     triple: TargetTriple,
217     extra_filename: String,
218     hash: Svh,
219     stable_crate_id: StableCrateId,
220     required_panic_strategy: Option<PanicStrategy>,
221     panic_in_drop_strategy: PanicStrategy,
222     edition: Edition,
223     has_global_allocator: bool,
224     has_panic_handler: bool,
225     has_default_lib_allocator: bool,
226
227     crate_deps: LazyArray<CrateDep>,
228     dylib_dependency_formats: LazyArray<Option<LinkagePreference>>,
229     lib_features: LazyArray<(Symbol, Option<Symbol>)>,
230     stability_implications: LazyArray<(Symbol, Symbol)>,
231     lang_items: LazyArray<(DefIndex, usize)>,
232     lang_items_missing: LazyArray<lang_items::LangItem>,
233     diagnostic_items: LazyArray<(Symbol, DefIndex)>,
234     native_libraries: LazyArray<NativeLib>,
235     foreign_modules: LazyArray<ForeignModule>,
236     traits: LazyArray<DefIndex>,
237     impls: LazyArray<TraitImpls>,
238     incoherent_impls: LazyArray<IncoherentImpls>,
239     interpret_alloc_index: LazyArray<u32>,
240     proc_macro_data: Option<ProcMacroData>,
241
242     tables: LazyTables,
243     debugger_visualizers: LazyArray<rustc_span::DebuggerVisualizerFile>,
244
245     exported_symbols: LazyArray<(ExportedSymbol<'static>, SymbolExportInfo)>,
246
247     syntax_contexts: SyntaxContextTable,
248     expn_data: ExpnDataTable,
249     expn_hashes: ExpnHashTable,
250
251     def_path_hash_map: LazyValue<DefPathHashMapRef<'static>>,
252
253     source_map: LazyTable<u32, LazyValue<rustc_span::SourceFile>>,
254
255     compiler_builtins: bool,
256     needs_allocator: bool,
257     needs_panic_runtime: bool,
258     no_builtins: bool,
259     panic_runtime: bool,
260     profiler_runtime: bool,
261     symbol_mangling_version: SymbolManglingVersion,
262 }
263
264 /// On-disk representation of `DefId`.
265 /// This creates a type-safe way to enforce that we remap the CrateNum between the on-disk
266 /// representation and the compilation session.
267 #[derive(Copy, Clone)]
268 pub(crate) struct RawDefId {
269     krate: u32,
270     index: u32,
271 }
272
273 impl Into<RawDefId> for DefId {
274     fn into(self) -> RawDefId {
275         RawDefId { krate: self.krate.as_u32(), index: self.index.as_u32() }
276     }
277 }
278
279 impl RawDefId {
280     /// This exists so that `provide_one!` is happy
281     fn decode(self, meta: (CrateMetadataRef<'_>, TyCtxt<'_>)) -> DefId {
282         self.decode_from_cdata(meta.0)
283     }
284
285     fn decode_from_cdata(self, cdata: CrateMetadataRef<'_>) -> DefId {
286         let krate = CrateNum::from_u32(self.krate);
287         let krate = cdata.map_encoded_cnum_to_current(krate);
288         DefId { krate, index: DefIndex::from_u32(self.index) }
289     }
290 }
291
292 #[derive(Encodable, Decodable)]
293 pub(crate) struct CrateDep {
294     pub name: Symbol,
295     pub hash: Svh,
296     pub host_hash: Option<Svh>,
297     pub kind: CrateDepKind,
298     pub extra_filename: String,
299 }
300
301 #[derive(MetadataEncodable, MetadataDecodable)]
302 pub(crate) struct TraitImpls {
303     trait_id: (u32, DefIndex),
304     impls: LazyArray<(DefIndex, Option<SimplifiedType>)>,
305 }
306
307 #[derive(MetadataEncodable, MetadataDecodable)]
308 pub(crate) struct IncoherentImpls {
309     self_ty: SimplifiedType,
310     impls: LazyArray<DefIndex>,
311 }
312
313 /// Define `LazyTables` and `TableBuilders` at the same time.
314 macro_rules! define_tables {
315     ($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
316         #[derive(MetadataEncodable, MetadataDecodable)]
317         pub(crate) struct LazyTables {
318             $($name: LazyTable<$IDX, $T>),+
319         }
320
321         #[derive(Default)]
322         struct TableBuilders {
323             $($name: TableBuilder<$IDX, $T>),+
324         }
325
326         impl TableBuilders {
327             fn encode(&self, buf: &mut FileEncoder) -> LazyTables {
328                 LazyTables {
329                     $($name: self.$name.encode(buf)),+
330                 }
331             }
332         }
333     }
334 }
335
336 define_tables! {
337     kind: Table<DefIndex, LazyValue<EntryKind>>,
338     attributes: Table<DefIndex, LazyArray<ast::Attribute>>,
339     children: Table<DefIndex, LazyArray<DefIndex>>,
340
341     opt_def_kind: Table<DefIndex, DefKind>,
342     visibility: Table<DefIndex, LazyValue<ty::Visibility>>,
343     def_span: Table<DefIndex, LazyValue<Span>>,
344     def_ident_span: Table<DefIndex, LazyValue<Span>>,
345     lookup_stability: Table<DefIndex, LazyValue<attr::Stability>>,
346     lookup_const_stability: Table<DefIndex, LazyValue<attr::ConstStability>>,
347     lookup_default_body_stability: Table<DefIndex, LazyValue<attr::DefaultBodyStability>>,
348     lookup_deprecation_entry: Table<DefIndex, LazyValue<attr::Deprecation>>,
349     // As an optimization, a missing entry indicates an empty `&[]`.
350     explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
351     explicit_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
352     generics_of: Table<DefIndex, LazyValue<ty::Generics>>,
353     // As an optimization, a missing entry indicates an empty `&[]`.
354     inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>,
355     super_predicates_of: Table<DefIndex, LazyValue<ty::GenericPredicates<'static>>>,
356     type_of: Table<DefIndex, LazyValue<Ty<'static>>>,
357     variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
358     fn_sig: Table<DefIndex, LazyValue<ty::PolyFnSig<'static>>>,
359     codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
360     impl_trait_ref: Table<DefIndex, LazyValue<ty::TraitRef<'static>>>,
361     const_param_default: Table<DefIndex, LazyValue<rustc_middle::ty::Const<'static>>>,
362     object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
363     optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
364     mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
365     promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
366     // FIXME(compiler-errors): Why isn't this a LazyArray?
367     thir_abstract_const: Table<DefIndex, LazyValue<&'static [ty::abstract_const::Node<'static>]>>,
368     impl_parent: Table<DefIndex, RawDefId>,
369     impl_polarity: Table<DefIndex, ty::ImplPolarity>,
370     constness: Table<DefIndex, hir::Constness>,
371     is_intrinsic: Table<DefIndex, ()>,
372     impl_defaultness: Table<DefIndex, hir::Defaultness>,
373     // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
374     coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
375     mir_const_qualif: Table<DefIndex, LazyValue<mir::ConstQualifs>>,
376     rendered_const: Table<DefIndex, LazyValue<String>>,
377     asyncness: Table<DefIndex, hir::IsAsync>,
378     fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
379     generator_kind: Table<DefIndex, LazyValue<hir::GeneratorKind>>,
380     trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
381
382     trait_item_def_id: Table<DefIndex, RawDefId>,
383     inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
384     expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
385     unused_generic_params: Table<DefIndex, LazyValue<FiniteBitSet<u32>>>,
386     repr_options: Table<DefIndex, LazyValue<ReprOptions>>,
387     // `def_keys` and `def_path_hashes` represent a lazy version of a
388     // `DefPathTable`. This allows us to avoid deserializing an entire
389     // `DefPathTable` up front, since we may only ever use a few
390     // definitions from any given crate.
391     def_keys: Table<DefIndex, LazyValue<DefKey>>,
392     def_path_hashes: Table<DefIndex, DefPathHash>,
393     proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
394     generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
395     may_have_doc_links: Table<DefIndex, ()>,
396     variant_data: Table<DefIndex, LazyValue<VariantData>>,
397 }
398
399 #[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
400 enum EntryKind {
401     AnonConst,
402     Const,
403     Static,
404     ForeignStatic,
405     ForeignMod,
406     ForeignType,
407     GlobalAsm,
408     Type,
409     TypeParam,
410     ConstParam,
411     OpaqueTy,
412     Enum,
413     Field,
414     Variant,
415     Struct,
416     Union,
417     Fn,
418     ForeignFn,
419     Mod(LazyArray<ModChild>),
420     MacroDef(LazyValue<ast::MacArgs>, /*macro_rules*/ bool),
421     ProcMacro(MacroKind),
422     Closure,
423     Generator,
424     Trait,
425     Impl,
426     AssocFn { container: ty::AssocItemContainer, has_self: bool },
427     AssocType(ty::AssocItemContainer),
428     AssocConst(ty::AssocItemContainer),
429     TraitAlias,
430 }
431
432 #[derive(TyEncodable, TyDecodable)]
433 struct VariantData {
434     ctor_kind: CtorKind,
435     discr: ty::VariantDiscr,
436     /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
437     ctor: Option<DefIndex>,
438     is_non_exhaustive: bool,
439 }
440
441 #[derive(TyEncodable, TyDecodable)]
442 struct GeneratorData<'tcx> {
443     layout: mir::GeneratorLayout<'tcx>,
444 }
445
446 // Tags used for encoding Spans:
447 const TAG_VALID_SPAN_LOCAL: u8 = 0;
448 const TAG_VALID_SPAN_FOREIGN: u8 = 1;
449 const TAG_PARTIAL_SPAN: u8 = 2;
450
451 // Tags for encoding Symbol's
452 const SYMBOL_STR: u8 = 0;
453 const SYMBOL_OFFSET: u8 = 1;
454 const SYMBOL_PREINTERNED: u8 = 2;
455
456 pub fn provide(providers: &mut Providers) {
457     encoder::provide(providers);
458     decoder::provide(providers);
459 }
460
461 trivially_parameterized_over_tcx! {
462     VariantData,
463     EntryKind,
464     RawDefId,
465     TraitImpls,
466     IncoherentImpls,
467     CrateRoot,
468     CrateDep,
469 }