]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_metadata/src/rmeta/mod.rs
New upstream version 1.60.0+dfsg1
[rustc.git] / compiler / rustc_metadata / src / rmeta / mod.rs
CommitLineData
60c5eb7d 1use decoder::Metadata;
c295e0f8 2use def_path_hash_map::DefPathHashMapRef;
60c5eb7d 3use table::{Table, TableBuilder};
9e0c209e 4
3dfed10e 5use rustc_ast::{self as ast, MacroDef};
74b04a01 6use rustc_attr as attr;
b7449926 7use rustc_data_structures::svh::Svh;
60c5eb7d 8use rustc_data_structures::sync::MetadataRef;
dfeec247 9use rustc_hir as hir;
5869c6ff 10use rustc_hir::def::{CtorKind, DefKind};
6a06907d 11use rustc_hir::def_id::{DefId, DefIndex, DefPathHash, StableCrateId};
3dfed10e 12use rustc_hir::definitions::DefKey;
ba9703b0 13use rustc_hir::lang_items;
3dfed10e 14use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
5099ac24 15use rustc_middle::metadata::ModChild;
ba9703b0
XL
16use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
17use rustc_middle::mir;
c295e0f8 18use rustc_middle::thir;
a2a8927a
XL
19use rustc_middle::ty::fast_reject::SimplifiedType;
20use rustc_middle::ty::query::Providers;
ba9703b0 21use rustc_middle::ty::{self, ReprOptions, Ty};
60c5eb7d 22use rustc_serialize::opaque::Encoder;
ba9703b0 23use rustc_session::config::SymbolManglingVersion;
c295e0f8 24use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
dfeec247 25use rustc_span::edition::Edition;
136023e0 26use rustc_span::hygiene::{ExpnIndex, MacroKind};
f035d41b 27use rustc_span::symbol::{Ident, Symbol};
136023e0 28use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
dfeec247 29use rustc_target::spec::{PanicStrategy, TargetTriple};
9e0c209e
SL
30
31use std::marker::PhantomData;
e74abb32 32use std::num::NonZeroUsize;
9e0c209e 33
a2a8927a 34pub use decoder::provide_extern;
3dfed10e 35use decoder::DecodeContext;
60c5eb7d 36crate use decoder::{CrateMetadata, CrateNumMap, MetadataBlob};
3dfed10e 37use encoder::EncodeContext;
c295e0f8 38pub use encoder::{encode_metadata, EncodedMetadata};
3dfed10e 39use rustc_span::hygiene::SyntaxContextData;
60c5eb7d
XL
40
41mod decoder;
c295e0f8 42mod def_path_hash_map;
60c5eb7d
XL
43mod encoder;
44mod table;
45
e74abb32 46crate fn rustc_version() -> String {
dfeec247 47 format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version"))
c30ab7b3 48}
9e0c209e
SL
49
50/// Metadata encoding version.
0731742a 51/// N.B., increment this if you change the format of metadata such that
476ff2be 52/// the rustc version can't be found to compare with `rustc_version()`.
a2a8927a 53const METADATA_VERSION: u8 = 6;
9e0c209e
SL
54
55/// Metadata header which includes `METADATA_VERSION`.
9e0c209e 56///
476ff2be
SL
57/// This header is followed by the position of the `CrateRoot`,
58/// which is encoded as a 32-bit big-endian unsigned integer,
59/// and further followed by the rustc version string.
17df50a5 60pub const METADATA_HEADER: &[u8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
9e0c209e 61
e1599b0c
XL
62/// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`,
63/// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).
60c5eb7d 64trait LazyMeta {
e1599b0c 65 type Meta: Copy + 'static;
e1599b0c
XL
66}
67
60c5eb7d 68impl<T> LazyMeta for T {
e1599b0c 69 type Meta = ();
e1599b0c
XL
70}
71
60c5eb7d 72impl<T> LazyMeta for [T] {
e1599b0c 73 type Meta = usize;
e1599b0c
XL
74}
75
9e0c209e
SL
76/// A value of type T referred to by its absolute position
77/// in the metadata, and which can be decoded lazily.
78///
79/// Metadata is effective a tree, encoded in post-order,
80/// and with the root's position written next to the header.
81/// That means every single `Lazy` points to some previous
82/// location in the metadata and is part of a larger node.
83///
84/// The first `Lazy` in a node is encoded as the backwards
85/// distance from the position where the containing node
86/// starts and where the `Lazy` points to, while the rest
87/// use the forward distance from the previous `Lazy`.
88/// Distances start at 1, as 0-byte nodes are invalid.
89/// Also invalid are nodes being referred in a different
90/// order than they were encoded in.
e1599b0c
XL
91///
92/// # Sequences (`Lazy<[T]>`)
9e0c209e
SL
93///
94/// Unlike `Lazy<Vec<T>>`, the length is encoded next to the
95/// position, not at the position, which means that the length
96/// doesn't need to be known before encoding all the elements.
97///
98/// If the length is 0, no position is encoded, but otherwise,
99/// the encoding is that of `Lazy`, with the distinction that
100/// the minimal distance the length of the sequence, i.e.
101/// it's assumed there's no 0-byte element in the sequence.
102#[must_use]
e1599b0c
XL
103// FIXME(#59875) the `Meta` parameter only exists to dodge
104// invariance wrt `T` (coming from the `meta: T::Meta` field).
60c5eb7d 105struct Lazy<T, Meta = <T as LazyMeta>::Meta>
dfeec247
XL
106where
107 T: ?Sized + LazyMeta<Meta = Meta>,
108 Meta: 'static + Copy,
e1599b0c 109{
60c5eb7d
XL
110 position: NonZeroUsize,
111 meta: Meta,
c30ab7b3 112 _marker: PhantomData<T>,
9e0c209e
SL
113}
114
e1599b0c 115impl<T: ?Sized + LazyMeta> Lazy<T> {
dfeec247
XL
116 fn from_position_and_meta(position: NonZeroUsize, meta: T::Meta) -> Lazy<T> {
117 Lazy { position, meta, _marker: PhantomData }
9e0c209e 118 }
e1599b0c 119}
9e0c209e 120
60c5eb7d
XL
121impl<T> Lazy<T> {
122 fn from_position(position: NonZeroUsize) -> Lazy<T> {
e1599b0c 123 Lazy::from_position_and_meta(position, ())
9e0c209e
SL
124 }
125}
126
60c5eb7d
XL
127impl<T> Lazy<[T]> {
128 fn empty() -> Lazy<[T]> {
e74abb32 129 Lazy::from_position_and_meta(NonZeroUsize::new(1).unwrap(), 0)
e1599b0c
XL
130 }
131}
132
133impl<T: ?Sized + LazyMeta> Copy for Lazy<T> {}
134impl<T: ?Sized + LazyMeta> Clone for Lazy<T> {
c30ab7b3
SL
135 fn clone(&self) -> Self {
136 *self
137 }
9e0c209e
SL
138}
139
e1599b0c 140/// Encoding / decoding state for `Lazy`.
9e0c209e 141#[derive(Copy, Clone, PartialEq, Eq, Debug)]
60c5eb7d 142enum LazyState {
9e0c209e
SL
143 /// Outside of a metadata node.
144 NoNode,
145
e1599b0c 146 /// Inside a metadata node, and before any `Lazy`.
9e0c209e 147 /// The position is that of the node itself.
e74abb32 148 NodeStart(NonZeroUsize),
9e0c209e 149
e1599b0c 150 /// Inside a metadata node, with a previous `Lazy`.
5099ac24 151 /// The position is where that previous `Lazy` would start.
e74abb32
XL
152 Previous(NonZeroUsize),
153}
154
155// FIXME(#59875) `Lazy!(T)` replaces `Lazy<T>`, passing the `Meta` parameter
156// manually, instead of relying on the default, to get the correct variance.
157// Only needed when `T` itself contains a parameter (e.g. `'tcx`).
158macro_rules! Lazy {
60c5eb7d 159 (Table<$I:ty, $T:ty>) => {Lazy<Table<$I, $T>, usize>};
e74abb32
XL
160 ([$T:ty]) => {Lazy<[$T], usize>};
161 ($T:ty) => {Lazy<$T, ()>};
9e0c209e
SL
162}
163
3dfed10e 164type SyntaxContextTable = Lazy<Table<u32, Lazy<SyntaxContextData>>>;
136023e0
XL
165type ExpnDataTable = Lazy<Table<ExpnIndex, Lazy<ExpnData>>>;
166type ExpnHashTable = Lazy<Table<ExpnIndex, Lazy<ExpnHash>>>;
3dfed10e 167
1b1a35ee
XL
168#[derive(MetadataEncodable, MetadataDecodable)]
169crate struct ProcMacroData {
170 proc_macro_decls_static: DefIndex,
171 stability: Option<attr::Stability>,
172 macros: Lazy<[DefIndex]>,
173}
174
175/// Serialized metadata for a crate.
176/// When compiling a proc-macro crate, we encode many of
177/// the `Lazy<[T]>` fields as `Lazy::empty()`. This serves two purposes:
178///
179/// 1. We avoid performing unnecessary work. Proc-macro crates can only
180/// export proc-macros functions, which are compiled into a shared library.
181/// As a result, a large amount of the information we normally store
182/// (e.g. optimized MIR) is unneeded by downstream crates.
183/// 2. We avoid serializing invalid `CrateNum`s. When we deserialize
184/// a proc-macro crate, we don't load any of its dependencies (since we
185/// just need to invoke a native function from the shared library).
186/// This means that any foreign `CrateNum`s that we serialize cannot be
187/// deserialized, since we will not know how to map them into the current
188/// compilation session. If we were to serialize a proc-macro crate like
189/// a normal crate, much of what we serialized would be unusable in addition
190/// to being unused.
3dfed10e 191#[derive(MetadataEncodable, MetadataDecodable)]
e74abb32 192crate struct CrateRoot<'tcx> {
60c5eb7d
XL
193 name: Symbol,
194 triple: TargetTriple,
195 extra_filename: String,
196 hash: Svh,
6a06907d 197 stable_crate_id: StableCrateId,
60c5eb7d 198 panic_strategy: PanicStrategy,
c295e0f8 199 panic_in_drop_strategy: PanicStrategy,
60c5eb7d
XL
200 edition: Edition,
201 has_global_allocator: bool,
202 has_panic_handler: bool,
203 has_default_lib_allocator: bool,
60c5eb7d
XL
204
205 crate_deps: Lazy<[CrateDep]>,
206 dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>,
207 lib_features: Lazy<[(Symbol, Option<Symbol>)]>,
208 lang_items: Lazy<[(DefIndex, usize)]>,
209 lang_items_missing: Lazy<[lang_items::LangItem]>,
210 diagnostic_items: Lazy<[(Symbol, DefIndex)]>,
f9f354fc 211 native_libraries: Lazy<[NativeLib]>,
60c5eb7d 212 foreign_modules: Lazy<[ForeignModule]>,
a2a8927a 213 traits: Lazy<[DefIndex]>,
60c5eb7d 214 impls: Lazy<[TraitImpls]>,
60c5eb7d 215 interpret_alloc_index: Lazy<[u32]>,
1b1a35ee 216 proc_macro_data: Option<ProcMacroData>,
60c5eb7d 217
ba9703b0 218 tables: LazyTables<'tcx>,
60c5eb7d 219
ba9703b0 220 exported_symbols: Lazy!([(ExportedSymbol<'tcx>, SymbolExportLevel)]),
3dfed10e
XL
221
222 syntax_contexts: SyntaxContextTable,
223 expn_data: ExpnDataTable,
136023e0 224 expn_hashes: ExpnHashTable,
3dfed10e 225
c295e0f8
XL
226 def_path_hash_map: Lazy<DefPathHashMapRef<'tcx>>,
227
f035d41b 228 source_map: Lazy<[rustc_span::SourceFile]>,
ba9703b0 229
60c5eb7d
XL
230 compiler_builtins: bool,
231 needs_allocator: bool,
232 needs_panic_runtime: bool,
233 no_builtins: bool,
234 panic_runtime: bool,
235 profiler_runtime: bool,
60c5eb7d 236 symbol_mangling_version: SymbolManglingVersion,
9e0c209e
SL
237}
238
3dfed10e 239#[derive(Encodable, Decodable)]
e74abb32 240crate struct CrateDep {
f9f354fc 241 pub name: Symbol,
b7449926 242 pub hash: Svh,
e74abb32 243 pub host_hash: Option<Svh>,
3dfed10e 244 pub kind: CrateDepKind,
83c7162d 245 pub extra_filename: String,
9e0c209e
SL
246}
247
3dfed10e 248#[derive(MetadataEncodable, MetadataDecodable)]
e74abb32 249crate struct TraitImpls {
60c5eb7d 250 trait_id: (u32, DefIndex),
a2a8927a 251 impls: Lazy<[(DefIndex, Option<SimplifiedType>)]>,
9e0c209e
SL
252}
253
ba9703b0
XL
254/// Define `LazyTables` and `TableBuilders` at the same time.
255macro_rules! define_tables {
17df50a5 256 ($($name:ident: Table<$IDX:ty, $T:ty>),+ $(,)?) => {
3dfed10e 257 #[derive(MetadataEncodable, MetadataDecodable)]
ba9703b0 258 crate struct LazyTables<'tcx> {
17df50a5 259 $($name: Lazy!(Table<$IDX, $T>)),+
60c5eb7d
XL
260 }
261
262 #[derive(Default)]
ba9703b0 263 struct TableBuilders<'tcx> {
17df50a5 264 $($name: TableBuilder<$IDX, $T>),+
60c5eb7d
XL
265 }
266
a2a8927a 267 impl<'tcx> TableBuilders<'tcx> {
ba9703b0
XL
268 fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
269 LazyTables {
60c5eb7d
XL
270 $($name: self.$name.encode(buf)),+
271 }
272 }
273 }
274 }
275}
276
ba9703b0 277define_tables! {
5869c6ff 278 def_kind: Table<DefIndex, Lazy<DefKind>>,
74b04a01 279 kind: Table<DefIndex, Lazy<EntryKind>>,
60c5eb7d
XL
280 visibility: Table<DefIndex, Lazy<ty::Visibility>>,
281 span: Table<DefIndex, Lazy<Span>>,
ba9703b0 282 ident_span: Table<DefIndex, Lazy<Span>>,
60c5eb7d
XL
283 attributes: Table<DefIndex, Lazy<[ast::Attribute]>>,
284 children: Table<DefIndex, Lazy<[DefIndex]>>,
285 stability: Table<DefIndex, Lazy<attr::Stability>>,
286 const_stability: Table<DefIndex, Lazy<attr::ConstStability>>,
287 deprecation: Table<DefIndex, Lazy<attr::Deprecation>>,
288 ty: Table<DefIndex, Lazy!(Ty<'tcx>)>,
289 fn_sig: Table<DefIndex, Lazy!(ty::PolyFnSig<'tcx>)>,
290 impl_trait_ref: Table<DefIndex, Lazy!(ty::TraitRef<'tcx>)>,
5099ac24 291 trait_item_def_id: Table<DefIndex, Lazy<DefId>>,
60c5eb7d
XL
292 inherent_impls: Table<DefIndex, Lazy<[DefIndex]>>,
293 variances: Table<DefIndex, Lazy<[ty::Variance]>>,
294 generics: Table<DefIndex, Lazy<ty::Generics>>,
295 explicit_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
29967ef6
XL
296 expn_that_defined: Table<DefIndex, Lazy<ExpnId>>,
297 // As an optimization, a missing entry indicates an empty `&[]`.
298 inferred_outlives: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>,
60c5eb7d 299 super_predicates: Table<DefIndex, Lazy!(ty::GenericPredicates<'tcx>)>,
29967ef6
XL
300 // As an optimization, a missing entry indicates an empty `&[]`.
301 explicit_item_bounds: Table<DefIndex, Lazy!([(ty::Predicate<'tcx>, Span)])>,
f9f354fc 302 mir: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
5869c6ff 303 mir_for_ctfe: Table<DefIndex, Lazy!(mir::Body<'tcx>)>,
f9f354fc 304 promoted_mir: Table<DefIndex, Lazy!(IndexVec<mir::Promoted, mir::Body<'tcx>>)>,
c295e0f8 305 thir_abstract_consts: Table<DefIndex, Lazy!(&'tcx [thir::abstract_const::Node<'tcx>])>,
cdc7bbd5 306 const_defaults: Table<DefIndex, Lazy<rustc_middle::ty::Const<'tcx>>>,
3dfed10e
XL
307 unused_generic_params: Table<DefIndex, Lazy<FiniteBitSet<u32>>>,
308 // `def_keys` and `def_path_hashes` represent a lazy version of a
309 // `DefPathTable`. This allows us to avoid deserializing an entire
310 // `DefPathTable` up front, since we may only ever use a few
311 // definitions from any given crate.
312 def_keys: Table<DefIndex, Lazy<DefKey>>,
cdc7bbd5 313 def_path_hashes: Table<DefIndex, Lazy<DefPathHash>>,
17df50a5 314 proc_macro_quoted_spans: Table<usize, Lazy<Span>>,
9e0c209e
SL
315}
316
3dfed10e 317#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
74b04a01 318enum EntryKind {
f035d41b 319 AnonConst(mir::ConstQualifs, Lazy<RenderedConst>),
60c5eb7d 320 Const(mir::ConstQualifs, Lazy<RenderedConst>),
9e0c209e
SL
321 ImmStatic,
322 MutStatic,
323 ForeignImmStatic,
324 ForeignMutStatic,
325 ForeignMod,
abe05a73 326 ForeignType,
cc61c64b 327 GlobalAsm,
9e0c209e 328 Type,
532ac7d7
XL
329 TypeParam,
330 ConstParam,
416331ca 331 OpaqueTy,
8bb4bdeb 332 Enum(ReprOptions),
9e0c209e 333 Field,
e74abb32
XL
334 Variant(Lazy<VariantData>),
335 Struct(Lazy<VariantData>, ReprOptions),
336 Union(Lazy<VariantData>, ReprOptions),
337 Fn(Lazy<FnData>),
338 ForeignFn(Lazy<FnData>),
5099ac24 339 Mod(Lazy<[ModChild]>),
476ff2be 340 MacroDef(Lazy<MacroDef>),
fc512014 341 ProcMacro(MacroKind),
e74abb32 342 Closure,
74b04a01 343 Generator(hir::GeneratorKind),
e74abb32
XL
344 Trait(Lazy<TraitData>),
345 Impl(Lazy<ImplData>),
ba9703b0 346 AssocFn(Lazy<AssocFnData>),
dc9dc135 347 AssocType(AssocContainer),
60c5eb7d 348 AssocConst(AssocContainer, mir::ConstQualifs, Lazy<RenderedConst>),
e74abb32 349 TraitAlias,
32a655c1
SL
350}
351
83c7162d
XL
352/// Contains a constant which has been rendered to a String.
353/// Used by rustdoc.
3dfed10e 354#[derive(Encodable, Decodable)]
60c5eb7d 355struct RenderedConst(String);
83c7162d 356
3dfed10e 357#[derive(MetadataEncodable, MetadataDecodable)]
60c5eb7d
XL
358struct FnData {
359 asyncness: hir::IsAsync,
360 constness: hir::Constness,
f035d41b 361 param_names: Lazy<[Ident]>,
9e0c209e
SL
362}
363
3dfed10e 364#[derive(TyEncodable, TyDecodable)]
60c5eb7d
XL
365struct VariantData {
366 ctor_kind: CtorKind,
367 discr: ty::VariantDiscr,
532ac7d7 368 /// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
60c5eb7d 369 ctor: Option<DefIndex>,
3dfed10e 370 is_non_exhaustive: bool,
9e0c209e
SL
371}
372
3dfed10e 373#[derive(TyEncodable, TyDecodable)]
60c5eb7d
XL
374struct TraitData {
375 unsafety: hir::Unsafety,
376 paren_sugar: bool,
377 has_auto_impl: bool,
378 is_marker: bool,
cdc7bbd5 379 skip_array_during_method_dispatch: bool,
ba9703b0 380 specialization_kind: ty::trait_def::TraitSpecializationKind,
5099ac24 381 must_implement_one_of: Option<Box<[Ident]>>,
9fa01778
XL
382}
383
3dfed10e 384#[derive(TyEncodable, TyDecodable)]
60c5eb7d
XL
385struct ImplData {
386 polarity: ty::ImplPolarity,
136023e0 387 constness: hir::Constness,
60c5eb7d
XL
388 defaultness: hir::Defaultness,
389 parent_impl: Option<DefId>,
cc61c64b
XL
390
391 /// This is `Some` only for impls of `CoerceUnsized`.
e74abb32 392 // FIXME(eddyb) perhaps compute this on the fly if cheap enough?
60c5eb7d 393 coerce_unsized_info: Option<ty::adjustment::CoerceUnsizedInfo>,
9e0c209e
SL
394}
395
396/// Describes whether the container of an associated item
397/// is a trait or an impl and whether, in a trait, it has
398/// a default, or an in impl, whether it's marked "default".
3dfed10e 399#[derive(Copy, Clone, TyEncodable, TyDecodable)]
60c5eb7d 400enum AssocContainer {
9e0c209e
SL
401 TraitRequired,
402 TraitWithDefault,
403 ImplDefault,
c30ab7b3 404 ImplFinal,
9e0c209e
SL
405}
406
dc9dc135 407impl AssocContainer {
60c5eb7d 408 fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
9e0c209e 409 match *self {
dfeec247
XL
410 AssocContainer::TraitRequired | AssocContainer::TraitWithDefault => {
411 ty::TraitContainer(def_id)
412 }
9e0c209e 413
dfeec247 414 AssocContainer::ImplDefault | AssocContainer::ImplFinal => ty::ImplContainer(def_id),
9e0c209e
SL
415 }
416 }
417
60c5eb7d 418 fn defaultness(&self) -> hir::Defaultness {
9e0c209e 419 match *self {
dfeec247
XL
420 AssocContainer::TraitRequired => hir::Defaultness::Default { has_value: false },
421
422 AssocContainer::TraitWithDefault | AssocContainer::ImplDefault => {
423 hir::Defaultness::Default { has_value: true }
424 }
9e0c209e 425
dc9dc135 426 AssocContainer::ImplFinal => hir::Defaultness::Final,
9e0c209e
SL
427 }
428 }
429}
430
3dfed10e 431#[derive(MetadataEncodable, MetadataDecodable)]
ba9703b0 432struct AssocFnData {
60c5eb7d
XL
433 fn_data: FnData,
434 container: AssocContainer,
435 has_self: bool,
9e0c209e
SL
436}
437
3dfed10e 438#[derive(TyEncodable, TyDecodable)]
60c5eb7d
XL
439struct GeneratorData<'tcx> {
440 layout: mir::GeneratorLayout<'tcx>,
ea8adc8c 441}
2c00a5a8
XL
442
443// Tags used for encoding Spans:
ba9703b0
XL
444const TAG_VALID_SPAN_LOCAL: u8 = 0;
445const TAG_VALID_SPAN_FOREIGN: u8 = 1;
cdc7bbd5 446const TAG_PARTIAL_SPAN: u8 = 2;
a2a8927a
XL
447
448pub fn provide(providers: &mut Providers) {
449 encoder::provide(providers);
450 decoder::provide(providers);
451}