]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_metadata/src/rmeta/encoder.rs
Create trait_def table.
[rust.git] / compiler / rustc_metadata / src / rmeta / encoder.rs
1 use crate::rmeta::def_path_hash_map::DefPathHashMapRef;
2 use crate::rmeta::table::{FixedSizeEncoding, TableBuilder};
3 use crate::rmeta::*;
4
5 use rustc_data_structures::fingerprint::Fingerprint;
6 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
7 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
8 use rustc_data_structures::sync::{join, par_iter, Lrc, ParallelIterator};
9 use rustc_hir as hir;
10 use rustc_hir::def::DefKind;
11 use rustc_hir::def_id::{
12     CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE,
13 };
14 use rustc_hir::definitions::DefPathData;
15 use rustc_hir::intravisit::{self, Visitor};
16 use rustc_hir::itemlikevisit::ItemLikeVisitor;
17 use rustc_hir::lang_items;
18 use rustc_hir::{AnonConst, GenericParamKind};
19 use rustc_index::bit_set::GrowableBitSet;
20 use rustc_index::vec::Idx;
21 use rustc_middle::hir::nested_filter;
22 use rustc_middle::middle::dependency_format::Linkage;
23 use rustc_middle::middle::exported_symbols::{
24     metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
25 };
26 use rustc_middle::mir::interpret;
27 use rustc_middle::thir;
28 use rustc_middle::traits::specialization_graph;
29 use rustc_middle::ty::codec::TyEncoder;
30 use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
31 use rustc_middle::ty::query::Providers;
32 use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
33 use rustc_serialize::{opaque, Encodable, Encoder};
34 use rustc_session::config::CrateType;
35 use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib};
36 use rustc_span::symbol::{sym, Ident, Symbol};
37 use rustc_span::{self, ExternalSource, FileName, SourceFile, Span, SyntaxContext};
38 use rustc_span::{
39     hygiene::{ExpnIndex, HygieneEncodeContext, MacroKind},
40     RealFileName,
41 };
42 use rustc_target::abi::VariantIdx;
43 use std::hash::Hash;
44 use std::num::NonZeroUsize;
45 use std::path::Path;
46 use tracing::{debug, trace};
47
48 pub(super) struct EncodeContext<'a, 'tcx> {
49     opaque: opaque::Encoder,
50     tcx: TyCtxt<'tcx>,
51     feat: &'tcx rustc_feature::Features,
52
53     tables: TableBuilders<'tcx>,
54
55     lazy_state: LazyState,
56     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
57     predicate_shorthands: FxHashMap<ty::PredicateKind<'tcx>, usize>,
58
59     interpret_allocs: FxIndexSet<interpret::AllocId>,
60
61     // This is used to speed up Span encoding.
62     // The `usize` is an index into the `MonotonicVec`
63     // that stores the `SourceFile`
64     source_file_cache: (Lrc<SourceFile>, usize),
65     // The indices (into the `SourceMap`'s `MonotonicVec`)
66     // of all of the `SourceFiles` that we need to serialize.
67     // When we serialize a `Span`, we insert the index of its
68     // `SourceFile` into the `GrowableBitSet`.
69     //
70     // This needs to be a `GrowableBitSet` and not a
71     // regular `BitSet` because we may actually import new `SourceFiles`
72     // during metadata encoding, due to executing a query
73     // with a result containing a foreign `Span`.
74     required_source_files: Option<GrowableBitSet<usize>>,
75     is_proc_macro: bool,
76     hygiene_ctxt: &'a HygieneEncodeContext,
77 }
78
79 /// If the current crate is a proc-macro, returns early with `Lazy:empty()`.
80 /// This is useful for skipping the encoding of things that aren't needed
81 /// for proc-macro crates.
82 macro_rules! empty_proc_macro {
83     ($self:ident) => {
84         if $self.is_proc_macro {
85             return Lazy::empty();
86         }
87     };
88 }
89
90 macro_rules! encoder_methods {
91     ($($name:ident($ty:ty);)*) => {
92         $(fn $name(&mut self, value: $ty) -> Result<(), Self::Error> {
93             self.opaque.$name(value)
94         })*
95     }
96 }
97
98 impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
99     type Error = <opaque::Encoder as Encoder>::Error;
100
101     #[inline]
102     fn emit_unit(&mut self) -> Result<(), Self::Error> {
103         Ok(())
104     }
105
106     encoder_methods! {
107         emit_usize(usize);
108         emit_u128(u128);
109         emit_u64(u64);
110         emit_u32(u32);
111         emit_u16(u16);
112         emit_u8(u8);
113
114         emit_isize(isize);
115         emit_i128(i128);
116         emit_i64(i64);
117         emit_i32(i32);
118         emit_i16(i16);
119         emit_i8(i8);
120
121         emit_bool(bool);
122         emit_f64(f64);
123         emit_f32(f32);
124         emit_char(char);
125         emit_str(&str);
126         emit_raw_bytes(&[u8]);
127     }
128 }
129
130 impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>>
131     for Lazy<T>
132 {
133     fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
134         e.emit_lazy_distance(*self)
135     }
136 }
137
138 impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>>
139     for Lazy<[T]>
140 {
141     fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
142         e.emit_usize(self.meta)?;
143         if self.meta == 0 {
144             return Ok(());
145         }
146         e.emit_lazy_distance(*self)
147     }
148 }
149
150 impl<'a, 'tcx, I: Idx, T: Encodable<EncodeContext<'a, 'tcx>>> Encodable<EncodeContext<'a, 'tcx>>
151     for Lazy<Table<I, T>>
152 where
153     Option<T>: FixedSizeEncoding,
154 {
155     fn encode(&self, e: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
156         e.emit_usize(self.meta)?;
157         e.emit_lazy_distance(*self)
158     }
159 }
160
161 impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for CrateNum {
162     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
163         if *self != LOCAL_CRATE && s.is_proc_macro {
164             panic!("Attempted to encode non-local CrateNum {:?} for proc-macro crate", self);
165         }
166         s.emit_u32(self.as_u32())
167     }
168 }
169
170 impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for DefIndex {
171     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
172         s.emit_u32(self.as_u32())
173     }
174 }
175
176 impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnIndex {
177     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
178         s.emit_u32(self.as_u32())
179     }
180 }
181
182 impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for SyntaxContext {
183     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
184         rustc_span::hygiene::raw_encode_syntax_context(*self, &s.hygiene_ctxt, s)
185     }
186 }
187
188 impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for ExpnId {
189     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
190         if self.krate == LOCAL_CRATE {
191             // We will only write details for local expansions.  Non-local expansions will fetch
192             // data from the corresponding crate's metadata.
193             // FIXME(#43047) FIXME(#74731) We may eventually want to avoid relying on external
194             // metadata from proc-macro crates.
195             s.hygiene_ctxt.schedule_expn_data_for_encoding(*self);
196         }
197         self.krate.encode(s)?;
198         self.local_id.encode(s)
199     }
200 }
201
202 impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
203     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
204         let span = self.data();
205
206         // Don't serialize any `SyntaxContext`s from a proc-macro crate,
207         // since we don't load proc-macro dependencies during serialization.
208         // This means that any hygiene information from macros used *within*
209         // a proc-macro crate (e.g. invoking a macro that expands to a proc-macro
210         // definition) will be lost.
211         //
212         // This can show up in two ways:
213         //
214         // 1. Any hygiene information associated with identifier of
215         // a proc macro (e.g. `#[proc_macro] pub fn $name`) will be lost.
216         // Since proc-macros can only be invoked from a different crate,
217         // real code should never need to care about this.
218         //
219         // 2. Using `Span::def_site` or `Span::mixed_site` will not
220         // include any hygiene information associated with the definition
221         // site. This means that a proc-macro cannot emit a `$crate`
222         // identifier which resolves to one of its dependencies,
223         // which also should never come up in practice.
224         //
225         // Additionally, this affects `Span::parent`, and any other
226         // span inspection APIs that would otherwise allow traversing
227         // the `SyntaxContexts` associated with a span.
228         //
229         // None of these user-visible effects should result in any
230         // cross-crate inconsistencies (getting one behavior in the same
231         // crate, and a different behavior in another crate) due to the
232         // limited surface that proc-macros can expose.
233         //
234         // IMPORTANT: If this is ever changed, be sure to update
235         // `rustc_span::hygiene::raw_encode_expn_id` to handle
236         // encoding `ExpnData` for proc-macro crates.
237         if s.is_proc_macro {
238             SyntaxContext::root().encode(s)?;
239         } else {
240             span.ctxt.encode(s)?;
241         }
242
243         if self.is_dummy() {
244             return TAG_PARTIAL_SPAN.encode(s);
245         }
246
247         // The Span infrastructure should make sure that this invariant holds:
248         debug_assert!(span.lo <= span.hi);
249
250         if !s.source_file_cache.0.contains(span.lo) {
251             let source_map = s.tcx.sess.source_map();
252             let source_file_index = source_map.lookup_source_file_idx(span.lo);
253             s.source_file_cache =
254                 (source_map.files()[source_file_index].clone(), source_file_index);
255         }
256
257         if !s.source_file_cache.0.contains(span.hi) {
258             // Unfortunately, macro expansion still sometimes generates Spans
259             // that malformed in this way.
260             return TAG_PARTIAL_SPAN.encode(s);
261         }
262
263         let source_files = s.required_source_files.as_mut().expect("Already encoded SourceMap!");
264         // Record the fact that we need to encode the data for this `SourceFile`
265         source_files.insert(s.source_file_cache.1);
266
267         // There are two possible cases here:
268         // 1. This span comes from a 'foreign' crate - e.g. some crate upstream of the
269         // crate we are writing metadata for. When the metadata for *this* crate gets
270         // deserialized, the deserializer will need to know which crate it originally came
271         // from. We use `TAG_VALID_SPAN_FOREIGN` to indicate that a `CrateNum` should
272         // be deserialized after the rest of the span data, which tells the deserializer
273         // which crate contains the source map information.
274         // 2. This span comes from our own crate. No special handling is needed - we just
275         // write `TAG_VALID_SPAN_LOCAL` to let the deserializer know that it should use
276         // our own source map information.
277         //
278         // If we're a proc-macro crate, we always treat this as a local `Span`.
279         // In `encode_source_map`, we serialize foreign `SourceFile`s into our metadata
280         // if we're a proc-macro crate.
281         // This allows us to avoid loading the dependencies of proc-macro crates: all of
282         // the information we need to decode `Span`s is stored in the proc-macro crate.
283         let (tag, lo, hi) = if s.source_file_cache.0.is_imported() && !s.is_proc_macro {
284             // To simplify deserialization, we 'rebase' this span onto the crate it originally came from
285             // (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values
286             // are relative to the source map information for the 'foreign' crate whose CrateNum
287             // we write into the metadata. This allows `imported_source_files` to binary
288             // search through the 'foreign' crate's source map information, using the
289             // deserialized 'lo' and 'hi' values directly.
290             //
291             // All of this logic ensures that the final result of deserialization is a 'normal'
292             // Span that can be used without any additional trouble.
293             let external_start_pos = {
294                 // Introduce a new scope so that we drop the 'lock()' temporary
295                 match &*s.source_file_cache.0.external_src.lock() {
296                     ExternalSource::Foreign { original_start_pos, .. } => *original_start_pos,
297                     src => panic!("Unexpected external source {:?}", src),
298                 }
299             };
300             let lo = (span.lo - s.source_file_cache.0.start_pos) + external_start_pos;
301             let hi = (span.hi - s.source_file_cache.0.start_pos) + external_start_pos;
302
303             (TAG_VALID_SPAN_FOREIGN, lo, hi)
304         } else {
305             (TAG_VALID_SPAN_LOCAL, span.lo, span.hi)
306         };
307
308         tag.encode(s)?;
309         lo.encode(s)?;
310
311         // Encode length which is usually less than span.hi and profits more
312         // from the variable-length integer encoding that we use.
313         let len = hi - lo;
314         len.encode(s)?;
315
316         if tag == TAG_VALID_SPAN_FOREIGN {
317             // This needs to be two lines to avoid holding the `s.source_file_cache`
318             // while calling `cnum.encode(s)`
319             let cnum = s.source_file_cache.0.cnum;
320             cnum.encode(s)?;
321         }
322
323         Ok(())
324     }
325 }
326
327 impl<'a, 'tcx> TyEncoder<'tcx> for EncodeContext<'a, 'tcx> {
328     const CLEAR_CROSS_CRATE: bool = true;
329
330     fn position(&self) -> usize {
331         self.opaque.position()
332     }
333
334     fn type_shorthands(&mut self) -> &mut FxHashMap<Ty<'tcx>, usize> {
335         &mut self.type_shorthands
336     }
337
338     fn predicate_shorthands(&mut self) -> &mut FxHashMap<ty::PredicateKind<'tcx>, usize> {
339         &mut self.predicate_shorthands
340     }
341
342     fn encode_alloc_id(
343         &mut self,
344         alloc_id: &rustc_middle::mir::interpret::AllocId,
345     ) -> Result<(), Self::Error> {
346         let (index, _) = self.interpret_allocs.insert_full(*alloc_id);
347
348         index.encode(self)
349     }
350 }
351
352 impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
353     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
354         (**self).encode(s)
355     }
356 }
357
358 impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
359     fn encode(&self, s: &mut EncodeContext<'a, 'tcx>) -> opaque::EncodeResult {
360         (**self).encode(s)
361     }
362 }
363
364 /// Helper trait to allow overloading `EncodeContext::lazy` for iterators.
365 trait EncodeContentsForLazy<'a, 'tcx, T: ?Sized + LazyMeta> {
366     fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) -> T::Meta;
367 }
368
369 impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> EncodeContentsForLazy<'a, 'tcx, T> for &T {
370     fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) {
371         self.encode(ecx).unwrap()
372     }
373 }
374
375 impl<'a, 'tcx, T: Encodable<EncodeContext<'a, 'tcx>>> EncodeContentsForLazy<'a, 'tcx, T> for T {
376     fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) {
377         self.encode(ecx).unwrap()
378     }
379 }
380
381 impl<'a, 'tcx, I, T: Encodable<EncodeContext<'a, 'tcx>>> EncodeContentsForLazy<'a, 'tcx, [T]> for I
382 where
383     I: IntoIterator,
384     I::Item: EncodeContentsForLazy<'a, 'tcx, T>,
385 {
386     fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'a, 'tcx>) -> usize {
387         self.into_iter().map(|value| value.encode_contents_for_lazy(ecx)).count()
388     }
389 }
390
391 // Shorthand for `$self.$tables.$table.set($def_id.index, $self.lazy($value))`, which would
392 // normally need extra variables to avoid errors about multiple mutable borrows.
393 macro_rules! record {
394     ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{
395         {
396             let value = $value;
397             let lazy = $self.lazy(value);
398             $self.$tables.$table.set($def_id.index, lazy);
399         }
400     }};
401 }
402
403 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
404     fn emit_lazy_distance<T: ?Sized + LazyMeta>(
405         &mut self,
406         lazy: Lazy<T>,
407     ) -> Result<(), <Self as Encoder>::Error> {
408         let pos = lazy.position.get();
409         let distance = match self.lazy_state {
410             LazyState::NoNode => bug!("emit_lazy_distance: outside of a metadata node"),
411             LazyState::NodeStart(start) => {
412                 let start = start.get();
413                 assert!(pos <= start);
414                 start - pos
415             }
416             LazyState::Previous(last_pos) => {
417                 assert!(
418                     last_pos <= lazy.position,
419                     "make sure that the calls to `lazy*` \
420                      are in the same order as the metadata fields",
421                 );
422                 lazy.position.get() - last_pos.get()
423             }
424         };
425         self.lazy_state = LazyState::Previous(NonZeroUsize::new(pos).unwrap());
426         self.emit_usize(distance)
427     }
428
429     fn lazy<T: ?Sized + LazyMeta>(
430         &mut self,
431         value: impl EncodeContentsForLazy<'a, 'tcx, T>,
432     ) -> Lazy<T> {
433         let pos = NonZeroUsize::new(self.position()).unwrap();
434
435         assert_eq!(self.lazy_state, LazyState::NoNode);
436         self.lazy_state = LazyState::NodeStart(pos);
437         let meta = value.encode_contents_for_lazy(self);
438         self.lazy_state = LazyState::NoNode;
439
440         assert!(pos.get() <= self.position());
441
442         Lazy::from_position_and_meta(pos, meta)
443     }
444
445     fn encode_info_for_items(&mut self) {
446         self.encode_info_for_mod(CRATE_DEF_ID, self.tcx.hir().root_module());
447
448         // Proc-macro crates only export proc-macro items, which are looked
449         // up using `proc_macro_data`
450         if self.is_proc_macro {
451             return;
452         }
453
454         self.tcx.hir().visit_all_item_likes(&mut self.as_deep_visitor());
455     }
456
457     fn encode_def_path_table(&mut self) {
458         let table = self.tcx.resolutions(()).definitions.def_path_table();
459         if self.is_proc_macro {
460             for def_index in std::iter::once(CRATE_DEF_INDEX)
461                 .chain(self.tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index))
462             {
463                 let def_key = self.lazy(table.def_key(def_index));
464                 let def_path_hash = self.lazy(table.def_path_hash(def_index));
465                 self.tables.def_keys.set(def_index, def_key);
466                 self.tables.def_path_hashes.set(def_index, def_path_hash);
467             }
468         } else {
469             for (def_index, def_key, def_path_hash) in table.enumerated_keys_and_path_hashes() {
470                 let def_key = self.lazy(def_key);
471                 let def_path_hash = self.lazy(def_path_hash);
472                 self.tables.def_keys.set(def_index, def_key);
473                 self.tables.def_path_hashes.set(def_index, def_path_hash);
474             }
475         }
476     }
477
478     fn encode_def_path_hash_map(&mut self) -> Lazy<DefPathHashMapRef<'tcx>> {
479         self.lazy(DefPathHashMapRef::BorrowedFromTcx(
480             self.tcx.resolutions(()).definitions.def_path_hash_to_def_index_map(),
481         ))
482     }
483
484     fn encode_source_map(&mut self) -> Lazy<[rustc_span::SourceFile]> {
485         let source_map = self.tcx.sess.source_map();
486         let all_source_files = source_map.files();
487
488         // By replacing the `Option` with `None`, we ensure that we can't
489         // accidentally serialize any more `Span`s after the source map encoding
490         // is done.
491         let required_source_files = self.required_source_files.take().unwrap();
492
493         let adapted = all_source_files
494             .iter()
495             .enumerate()
496             .filter(|(idx, source_file)| {
497                 // Only serialize `SourceFile`s that were used
498                 // during the encoding of a `Span`
499                 required_source_files.contains(*idx) &&
500                 // Don't serialize imported `SourceFile`s, unless
501                 // we're in a proc-macro crate.
502                 (!source_file.is_imported() || self.is_proc_macro)
503             })
504             .map(|(_, source_file)| {
505                 let mut adapted = match source_file.name {
506                     FileName::Real(ref realname) => {
507                         let mut adapted = (**source_file).clone();
508                         adapted.name = FileName::Real(match realname {
509                             RealFileName::LocalPath(path_to_file) => {
510                                 // Prepend path of working directory onto potentially
511                                 // relative paths, because they could become relative
512                                 // to a wrong directory.
513                                 // We include `working_dir` as part of the crate hash,
514                                 // so it's okay for us to use it as part of the encoded
515                                 // metadata.
516                                 let working_dir = &self.tcx.sess.opts.working_dir;
517                                 match working_dir {
518                                     RealFileName::LocalPath(absolute) => {
519                                         // Although neither working_dir or the file name were subject
520                                         // to path remapping, the concatenation between the two may
521                                         // be. Hence we need to do a remapping here.
522                                         let joined = Path::new(absolute).join(path_to_file);
523                                         let (joined, remapped) =
524                                             source_map.path_mapping().map_prefix(joined);
525                                         if remapped {
526                                             RealFileName::Remapped {
527                                                 local_path: None,
528                                                 virtual_name: joined,
529                                             }
530                                         } else {
531                                             RealFileName::LocalPath(joined)
532                                         }
533                                     }
534                                     RealFileName::Remapped { local_path: _, virtual_name } => {
535                                         // If working_dir has been remapped, then we emit
536                                         // Remapped variant as the expanded path won't be valid
537                                         RealFileName::Remapped {
538                                             local_path: None,
539                                             virtual_name: Path::new(virtual_name)
540                                                 .join(path_to_file),
541                                         }
542                                     }
543                                 }
544                             }
545                             RealFileName::Remapped { local_path: _, virtual_name } => {
546                                 RealFileName::Remapped {
547                                     // We do not want any local path to be exported into metadata
548                                     local_path: None,
549                                     virtual_name: virtual_name.clone(),
550                                 }
551                             }
552                         });
553                         adapted.name_hash = {
554                             let mut hasher: StableHasher = StableHasher::new();
555                             adapted.name.hash(&mut hasher);
556                             hasher.finish::<u128>()
557                         };
558                         Lrc::new(adapted)
559                     }
560
561                     // expanded code, not from a file
562                     _ => source_file.clone(),
563                 };
564
565                 // We're serializing this `SourceFile` into our crate metadata,
566                 // so mark it as coming from this crate.
567                 // This also ensures that we don't try to deserialize the
568                 // `CrateNum` for a proc-macro dependency - since proc macro
569                 // dependencies aren't loaded when we deserialize a proc-macro,
570                 // trying to remap the `CrateNum` would fail.
571                 if self.is_proc_macro {
572                     Lrc::make_mut(&mut adapted).cnum = LOCAL_CRATE;
573                 }
574                 adapted
575             })
576             .collect::<Vec<_>>();
577
578         self.lazy(adapted.iter().map(|rc| &**rc))
579     }
580
581     fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
582         let tcx = self.tcx;
583         let mut i = self.position();
584
585         // Encode the crate deps
586         let crate_deps = self.encode_crate_deps();
587         let dylib_dependency_formats = self.encode_dylib_dependency_formats();
588         let dep_bytes = self.position() - i;
589
590         // Encode the lib features.
591         i = self.position();
592         let lib_features = self.encode_lib_features();
593         let lib_feature_bytes = self.position() - i;
594
595         // Encode the language items.
596         i = self.position();
597         let lang_items = self.encode_lang_items();
598         let lang_items_missing = self.encode_lang_items_missing();
599         let lang_item_bytes = self.position() - i;
600
601         // Encode the diagnostic items.
602         i = self.position();
603         let diagnostic_items = self.encode_diagnostic_items();
604         let diagnostic_item_bytes = self.position() - i;
605
606         // Encode the native libraries used
607         i = self.position();
608         let native_libraries = self.encode_native_libraries();
609         let native_lib_bytes = self.position() - i;
610
611         let foreign_modules = self.encode_foreign_modules();
612
613         // Encode DefPathTable
614         i = self.position();
615         self.encode_def_path_table();
616         let def_path_table_bytes = self.position() - i;
617
618         // Encode the def IDs of traits, for rustdoc and diagnostics.
619         i = self.position();
620         let traits = self.encode_traits();
621         let traits_bytes = self.position() - i;
622
623         // Encode the def IDs of impls, for coherence checking.
624         i = self.position();
625         let impls = self.encode_impls();
626         let impls_bytes = self.position() - i;
627
628         i = self.position();
629         let incoherent_impls = self.encode_incoherent_impls();
630         let incoherent_impls_bytes = self.position() - i;
631         // Encode MIR.
632         i = self.position();
633         self.encode_mir();
634         let mir_bytes = self.position() - i;
635
636         // Encode the items.
637         i = self.position();
638         self.encode_def_ids();
639         self.encode_info_for_items();
640         let item_bytes = self.position() - i;
641
642         // Encode the allocation index
643         let interpret_alloc_index = {
644             let mut interpret_alloc_index = Vec::new();
645             let mut n = 0;
646             trace!("beginning to encode alloc ids");
647             loop {
648                 let new_n = self.interpret_allocs.len();
649                 // if we have found new ids, serialize those, too
650                 if n == new_n {
651                     // otherwise, abort
652                     break;
653                 }
654                 trace!("encoding {} further alloc ids", new_n - n);
655                 for idx in n..new_n {
656                     let id = self.interpret_allocs[idx];
657                     let pos = self.position() as u32;
658                     interpret_alloc_index.push(pos);
659                     interpret::specialized_encode_alloc_id(self, tcx, id).unwrap();
660                 }
661                 n = new_n;
662             }
663             self.lazy(interpret_alloc_index)
664         };
665
666         // Encode the proc macro data. This affects 'tables',
667         // so we need to do this before we encode the tables
668         i = self.position();
669         let proc_macro_data = self.encode_proc_macros();
670         let proc_macro_data_bytes = self.position() - i;
671
672         i = self.position();
673         let tables = self.tables.encode(&mut self.opaque);
674         let tables_bytes = self.position() - i;
675
676         // Encode exported symbols info. This is prefetched in `encode_metadata` so we encode
677         // this as late as possible to give the prefetching as much time as possible to complete.
678         i = self.position();
679         let exported_symbols = tcx.exported_symbols(LOCAL_CRATE);
680         let exported_symbols = self.encode_exported_symbols(&exported_symbols);
681         let exported_symbols_bytes = self.position() - i;
682
683         // Encode the hygiene data,
684         // IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The process
685         // of encoding other items (e.g. `optimized_mir`) may cause us to load
686         // data from the incremental cache. If this causes us to deserialize a `Span`,
687         // then we may load additional `SyntaxContext`s into the global `HygieneData`.
688         // Therefore, we need to encode the hygiene data last to ensure that we encode
689         // any `SyntaxContext`s that might be used.
690         i = self.position();
691         let (syntax_contexts, expn_data, expn_hashes) = self.encode_hygiene();
692         let hygiene_bytes = self.position() - i;
693
694         i = self.position();
695         let def_path_hash_map = self.encode_def_path_hash_map();
696         let def_path_hash_map_bytes = self.position() - i;
697
698         // Encode source_map. This needs to be done last,
699         // since encoding `Span`s tells us which `SourceFiles` we actually
700         // need to encode.
701         i = self.position();
702         let source_map = self.encode_source_map();
703         let source_map_bytes = self.position() - i;
704
705         let attrs = tcx.hir().krate_attrs();
706         let has_default_lib_allocator = tcx.sess.contains_name(&attrs, sym::default_lib_allocator);
707
708         let root = self.lazy(CrateRoot {
709             name: tcx.crate_name(LOCAL_CRATE),
710             extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
711             triple: tcx.sess.opts.target_triple.clone(),
712             hash: tcx.crate_hash(LOCAL_CRATE),
713             stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(),
714             panic_strategy: tcx.sess.panic_strategy(),
715             panic_in_drop_strategy: tcx.sess.opts.debugging_opts.panic_in_drop,
716             edition: tcx.sess.edition(),
717             has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
718             has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
719             has_default_lib_allocator,
720             proc_macro_data,
721             compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins),
722             needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator),
723             needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime),
724             no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
725             panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
726             profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
727             symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(),
728
729             crate_deps,
730             dylib_dependency_formats,
731             lib_features,
732             lang_items,
733             diagnostic_items,
734             lang_items_missing,
735             native_libraries,
736             foreign_modules,
737             source_map,
738             traits,
739             impls,
740             incoherent_impls,
741             exported_symbols,
742             interpret_alloc_index,
743             tables,
744             syntax_contexts,
745             expn_data,
746             expn_hashes,
747             def_path_hash_map,
748         });
749
750         let total_bytes = self.position();
751
752         if tcx.sess.meta_stats() {
753             let mut zero_bytes = 0;
754             for e in self.opaque.data.iter() {
755                 if *e == 0 {
756                     zero_bytes += 1;
757                 }
758             }
759
760             eprintln!("metadata stats:");
761             eprintln!("             dep bytes: {}", dep_bytes);
762             eprintln!("     lib feature bytes: {}", lib_feature_bytes);
763             eprintln!("       lang item bytes: {}", lang_item_bytes);
764             eprintln!(" diagnostic item bytes: {}", diagnostic_item_bytes);
765             eprintln!("          native bytes: {}", native_lib_bytes);
766             eprintln!("      source_map bytes: {}", source_map_bytes);
767             eprintln!("          traits bytes: {}", traits_bytes);
768             eprintln!("           impls bytes: {}", impls_bytes);
769             eprintln!("incoherent_impls bytes: {}", incoherent_impls_bytes);
770             eprintln!("    exp. symbols bytes: {}", exported_symbols_bytes);
771             eprintln!("  def-path table bytes: {}", def_path_table_bytes);
772             eprintln!(" def-path hashes bytes: {}", def_path_hash_map_bytes);
773             eprintln!(" proc-macro-data-bytes: {}", proc_macro_data_bytes);
774             eprintln!("             mir bytes: {}", mir_bytes);
775             eprintln!("            item bytes: {}", item_bytes);
776             eprintln!("           table bytes: {}", tables_bytes);
777             eprintln!("         hygiene bytes: {}", hygiene_bytes);
778             eprintln!("            zero bytes: {}", zero_bytes);
779             eprintln!("           total bytes: {}", total_bytes);
780         }
781
782         root
783     }
784 }
785
786 fn should_encode_visibility(def_kind: DefKind) -> bool {
787     match def_kind {
788         DefKind::Mod
789         | DefKind::Struct
790         | DefKind::Union
791         | DefKind::Enum
792         | DefKind::Variant
793         | DefKind::Trait
794         | DefKind::TyAlias
795         | DefKind::ForeignTy
796         | DefKind::TraitAlias
797         | DefKind::AssocTy
798         | DefKind::Fn
799         | DefKind::Const
800         | DefKind::Static(..)
801         | DefKind::Ctor(..)
802         | DefKind::AssocFn
803         | DefKind::AssocConst
804         | DefKind::Macro(..)
805         | DefKind::Use
806         | DefKind::ForeignMod
807         | DefKind::OpaqueTy
808         | DefKind::Impl
809         | DefKind::Field => true,
810         DefKind::TyParam
811         | DefKind::ConstParam
812         | DefKind::LifetimeParam
813         | DefKind::AnonConst
814         | DefKind::InlineConst
815         | DefKind::GlobalAsm
816         | DefKind::Closure
817         | DefKind::Generator
818         | DefKind::ExternCrate => false,
819     }
820 }
821
822 fn should_encode_stability(def_kind: DefKind) -> bool {
823     match def_kind {
824         DefKind::Mod
825         | DefKind::Ctor(..)
826         | DefKind::Variant
827         | DefKind::Field
828         | DefKind::Struct
829         | DefKind::AssocTy
830         | DefKind::AssocFn
831         | DefKind::AssocConst
832         | DefKind::TyParam
833         | DefKind::ConstParam
834         | DefKind::Static(..)
835         | DefKind::Const
836         | DefKind::Fn
837         | DefKind::ForeignMod
838         | DefKind::TyAlias
839         | DefKind::OpaqueTy
840         | DefKind::Enum
841         | DefKind::Union
842         | DefKind::Impl
843         | DefKind::Trait
844         | DefKind::TraitAlias
845         | DefKind::Macro(..)
846         | DefKind::ForeignTy => true,
847         DefKind::Use
848         | DefKind::LifetimeParam
849         | DefKind::AnonConst
850         | DefKind::InlineConst
851         | DefKind::GlobalAsm
852         | DefKind::Closure
853         | DefKind::Generator
854         | DefKind::ExternCrate => false,
855     }
856 }
857
858 /// Whether we should encode MIR.
859 ///
860 /// Computing, optimizing and encoding the MIR is a relatively expensive operation.
861 /// We want to avoid this work when not required. Therefore:
862 /// - we only compute `mir_for_ctfe` on items with const-eval semantics;
863 /// - we skip `optimized_mir` for check runs.
864 ///
865 /// Return a pair, resp. for CTFE and for LLVM.
866 fn should_encode_mir(tcx: TyCtxt<'_>, def_id: LocalDefId) -> (bool, bool) {
867     match tcx.def_kind(def_id) {
868         // Constructors
869         DefKind::Ctor(_, _) => {
870             let mir_opt_base = tcx.sess.opts.output_types.should_codegen()
871                 || tcx.sess.opts.debugging_opts.always_encode_mir;
872             (true, mir_opt_base)
873         }
874         // Constants
875         DefKind::AnonConst
876         | DefKind::InlineConst
877         | DefKind::AssocConst
878         | DefKind::Static(..)
879         | DefKind::Const => (true, false),
880         // Full-fledged functions
881         DefKind::AssocFn | DefKind::Fn => {
882             let generics = tcx.generics_of(def_id);
883             let needs_inline = (generics.requires_monomorphization(tcx)
884                 || tcx.codegen_fn_attrs(def_id).requests_inline())
885                 && tcx.sess.opts.output_types.should_codegen();
886             // The function has a `const` modifier or is annotated with `default_method_body_is_const`.
887             let is_const_fn = tcx.is_const_fn_raw(def_id.to_def_id())
888                 || tcx.has_attr(def_id.to_def_id(), sym::default_method_body_is_const);
889             let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir;
890             (is_const_fn, needs_inline || always_encode_mir)
891         }
892         // Closures can't be const fn.
893         DefKind::Closure => {
894             let generics = tcx.generics_of(def_id);
895             let needs_inline = (generics.requires_monomorphization(tcx)
896                 || tcx.codegen_fn_attrs(def_id).requests_inline())
897                 && tcx.sess.opts.output_types.should_codegen();
898             let always_encode_mir = tcx.sess.opts.debugging_opts.always_encode_mir;
899             (false, needs_inline || always_encode_mir)
900         }
901         // Generators require optimized MIR to compute layout.
902         DefKind::Generator => (false, true),
903         // The others don't have MIR.
904         _ => (false, false),
905     }
906 }
907
908 fn should_encode_variances(def_kind: DefKind) -> bool {
909     match def_kind {
910         DefKind::Struct
911         | DefKind::Union
912         | DefKind::Enum
913         | DefKind::Variant
914         | DefKind::Fn
915         | DefKind::Ctor(..)
916         | DefKind::AssocFn => true,
917         DefKind::Mod
918         | DefKind::Field
919         | DefKind::AssocTy
920         | DefKind::AssocConst
921         | DefKind::TyParam
922         | DefKind::ConstParam
923         | DefKind::Static(..)
924         | DefKind::Const
925         | DefKind::ForeignMod
926         | DefKind::TyAlias
927         | DefKind::OpaqueTy
928         | DefKind::Impl
929         | DefKind::Trait
930         | DefKind::TraitAlias
931         | DefKind::Macro(..)
932         | DefKind::ForeignTy
933         | DefKind::Use
934         | DefKind::LifetimeParam
935         | DefKind::AnonConst
936         | DefKind::InlineConst
937         | DefKind::GlobalAsm
938         | DefKind::Closure
939         | DefKind::Generator
940         | DefKind::ExternCrate => false,
941     }
942 }
943
944 fn should_encode_generics(def_kind: DefKind) -> bool {
945     match def_kind {
946         DefKind::Struct
947         | DefKind::Union
948         | DefKind::Enum
949         | DefKind::Variant
950         | DefKind::Trait
951         | DefKind::TyAlias
952         | DefKind::ForeignTy
953         | DefKind::TraitAlias
954         | DefKind::AssocTy
955         | DefKind::Fn
956         | DefKind::Const
957         | DefKind::Static(..)
958         | DefKind::Ctor(..)
959         | DefKind::AssocFn
960         | DefKind::AssocConst
961         | DefKind::AnonConst
962         | DefKind::InlineConst
963         | DefKind::OpaqueTy
964         | DefKind::Impl
965         | DefKind::Field
966         | DefKind::TyParam
967         | DefKind::Closure
968         | DefKind::Generator => true,
969         DefKind::Mod
970         | DefKind::ForeignMod
971         | DefKind::ConstParam
972         | DefKind::Macro(..)
973         | DefKind::Use
974         | DefKind::LifetimeParam
975         | DefKind::GlobalAsm
976         | DefKind::ExternCrate => false,
977     }
978 }
979
980 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
981     fn encode_def_ids(&mut self) {
982         if self.is_proc_macro {
983             return;
984         }
985         let tcx = self.tcx;
986         let hir = tcx.hir();
987         for local_id in hir.iter_local_def_id() {
988             let def_id = local_id.to_def_id();
989             let def_kind = tcx.opt_def_kind(local_id);
990             let Some(def_kind) = def_kind else { continue };
991             record!(self.tables.opt_def_kind[def_id] <- def_kind);
992             record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
993             record!(self.tables.attributes[def_id] <- tcx.get_attrs(def_id));
994             record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
995             if should_encode_visibility(def_kind) {
996                 record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
997             }
998             if should_encode_stability(def_kind) {
999                 self.encode_stability(def_id);
1000                 self.encode_const_stability(def_id);
1001                 self.encode_deprecation(def_id);
1002             }
1003             if should_encode_variances(def_kind) {
1004                 let v = self.tcx.variances_of(def_id);
1005                 record!(self.tables.variances_of[def_id] <- v);
1006             }
1007             if should_encode_generics(def_kind) {
1008                 let g = tcx.generics_of(def_id);
1009                 record!(self.tables.generics_of[def_id] <- g);
1010                 record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id));
1011                 let inferred_outlives = self.tcx.inferred_outlives_of(def_id);
1012                 if !inferred_outlives.is_empty() {
1013                     record!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
1014                 }
1015             }
1016             if let DefKind::Trait | DefKind::TraitAlias = def_kind {
1017                 record!(self.tables.super_predicates_of[def_id] <- self.tcx.super_predicates_of(def_id));
1018             }
1019         }
1020         let inherent_impls = tcx.crate_inherent_impls(());
1021         for (def_id, implementations) in inherent_impls.inherent_impls.iter() {
1022             if implementations.is_empty() {
1023                 continue;
1024             }
1025             record!(self.tables.inherent_impls[def_id.to_def_id()] <- implementations.iter().map(|&def_id| {
1026                 assert!(def_id.is_local());
1027                 def_id.index
1028             }));
1029         }
1030     }
1031
1032     fn encode_item_type(&mut self, def_id: DefId) {
1033         debug!("EncodeContext::encode_item_type({:?})", def_id);
1034         record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
1035     }
1036
1037     fn encode_enum_variant_info(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
1038         let tcx = self.tcx;
1039         let variant = &def.variant(index);
1040         let def_id = variant.def_id;
1041         debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);
1042
1043         let data = VariantData {
1044             ctor_kind: variant.ctor_kind,
1045             discr: variant.discr,
1046             ctor: variant.ctor_def_id.map(|did| did.index),
1047             is_non_exhaustive: variant.is_field_list_non_exhaustive(),
1048         };
1049
1050         record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
1051         record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| {
1052             assert!(f.did.is_local());
1053             f.did.index
1054         }));
1055         self.encode_ident_span(def_id, variant.ident(tcx));
1056         self.encode_item_type(def_id);
1057         if variant.ctor_kind == CtorKind::Fn {
1058             // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`.
1059             if let Some(ctor_def_id) = variant.ctor_def_id {
1060                 record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id));
1061             }
1062         }
1063     }
1064
1065     fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) {
1066         let tcx = self.tcx;
1067         let variant = &def.variant(index);
1068         let def_id = variant.ctor_def_id.unwrap();
1069         debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
1070
1071         // FIXME(eddyb) encode only the `CtorKind` for constructors.
1072         let data = VariantData {
1073             ctor_kind: variant.ctor_kind,
1074             discr: variant.discr,
1075             ctor: Some(def_id.index),
1076             is_non_exhaustive: variant.is_field_list_non_exhaustive(),
1077         };
1078
1079         record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data)));
1080         self.encode_item_type(def_id);
1081         if variant.ctor_kind == CtorKind::Fn {
1082             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1083         }
1084     }
1085
1086     fn encode_info_for_mod(&mut self, local_def_id: LocalDefId, md: &hir::Mod<'_>) {
1087         let tcx = self.tcx;
1088         let def_id = local_def_id.to_def_id();
1089         debug!("EncodeContext::encode_info_for_mod({:?})", def_id);
1090
1091         // If we are encoding a proc-macro crates, `encode_info_for_mod` will
1092         // only ever get called for the crate root. We still want to encode
1093         // the crate root for consistency with other crates (some of the resolver
1094         // code uses it). However, we skip encoding anything relating to child
1095         // items - we encode information about proc-macros later on.
1096         let reexports = if !self.is_proc_macro {
1097             match tcx.module_reexports(local_def_id) {
1098                 Some(exports) => self.lazy(exports),
1099                 _ => Lazy::empty(),
1100             }
1101         } else {
1102             Lazy::empty()
1103         };
1104
1105         record!(self.tables.kind[def_id] <- EntryKind::Mod(reexports));
1106         if self.is_proc_macro {
1107             // Encode this here because we don't do it in encode_def_ids.
1108             record!(self.tables.expn_that_defined[def_id] <- tcx.expn_that_defined(local_def_id));
1109         } else {
1110             let direct_children = md.item_ids.iter().map(|item_id| item_id.def_id.local_def_index);
1111             // Foreign items are planted into their parent modules from name resolution point of view.
1112             let tcx = self.tcx;
1113             let foreign_item_children = md
1114                 .item_ids
1115                 .iter()
1116                 .filter_map(|item_id| match tcx.hir().item(*item_id).kind {
1117                     hir::ItemKind::ForeignMod { items, .. } => {
1118                         Some(items.iter().map(|fi_ref| fi_ref.id.def_id.local_def_index))
1119                     }
1120                     _ => None,
1121                 })
1122                 .flatten();
1123
1124             record!(self.tables.children[def_id] <- direct_children.chain(foreign_item_children));
1125         }
1126     }
1127
1128     fn encode_field(
1129         &mut self,
1130         adt_def: ty::AdtDef<'tcx>,
1131         variant_index: VariantIdx,
1132         field_index: usize,
1133     ) {
1134         let variant = &adt_def.variant(variant_index);
1135         let field = &variant.fields[field_index];
1136
1137         let def_id = field.did;
1138         debug!("EncodeContext::encode_field({:?})", def_id);
1139
1140         record!(self.tables.kind[def_id] <- EntryKind::Field);
1141         self.encode_ident_span(def_id, field.ident(self.tcx));
1142         self.encode_item_type(def_id);
1143     }
1144
1145     fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) {
1146         debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
1147         let tcx = self.tcx;
1148         let variant = adt_def.non_enum_variant();
1149
1150         let data = VariantData {
1151             ctor_kind: variant.ctor_kind,
1152             discr: variant.discr,
1153             ctor: Some(def_id.index),
1154             is_non_exhaustive: variant.is_field_list_non_exhaustive(),
1155         };
1156
1157         record!(self.tables.repr_options[def_id] <- adt_def.repr());
1158         record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data)));
1159         self.encode_item_type(def_id);
1160         if variant.ctor_kind == CtorKind::Fn {
1161             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1162         }
1163     }
1164
1165     fn encode_explicit_item_bounds(&mut self, def_id: DefId) {
1166         debug!("EncodeContext::encode_explicit_item_bounds({:?})", def_id);
1167         let bounds = self.tcx.explicit_item_bounds(def_id);
1168         if !bounds.is_empty() {
1169             record!(self.tables.explicit_item_bounds[def_id] <- bounds);
1170         }
1171     }
1172
1173     fn encode_info_for_trait_item(&mut self, def_id: DefId) {
1174         debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id);
1175         let tcx = self.tcx;
1176
1177         let ast_item = tcx.hir().expect_trait_item(def_id.expect_local());
1178         let trait_item = tcx.associated_item(def_id);
1179
1180         let container = match trait_item.defaultness {
1181             hir::Defaultness::Default { has_value: true } => AssocContainer::TraitWithDefault,
1182             hir::Defaultness::Default { has_value: false } => AssocContainer::TraitRequired,
1183             hir::Defaultness::Final => span_bug!(ast_item.span, "traits cannot have final items"),
1184         };
1185
1186         match trait_item.kind {
1187             ty::AssocKind::Const => {
1188                 let rendered = rustc_hir_pretty::to_string(
1189                     &(&self.tcx.hir() as &dyn intravisit::Map<'_>),
1190                     |s| s.print_trait_item(ast_item),
1191                 );
1192
1193                 record!(self.tables.kind[def_id] <- EntryKind::AssocConst(container));
1194                 record!(self.tables.mir_const_qualif[def_id] <- mir::ConstQualifs::default());
1195                 record!(self.tables.rendered_const[def_id] <- rendered);
1196             }
1197             ty::AssocKind::Fn => {
1198                 let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind else { bug!() };
1199                 match *m {
1200                     hir::TraitFn::Required(ref names) => {
1201                         record!(self.tables.fn_arg_names[def_id] <- *names)
1202                     }
1203                     hir::TraitFn::Provided(body) => {
1204                         record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body))
1205                     }
1206                 };
1207                 record!(self.tables.asyncness[def_id] <- m_sig.header.asyncness);
1208                 record!(self.tables.impl_constness[def_id] <- hir::Constness::NotConst);
1209                 record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
1210                     container,
1211                     has_self: trait_item.fn_has_self_parameter,
1212                 })));
1213             }
1214             ty::AssocKind::Type => {
1215                 self.encode_explicit_item_bounds(def_id);
1216                 record!(self.tables.kind[def_id] <- EntryKind::AssocType(container));
1217             }
1218         }
1219         self.encode_ident_span(def_id, ast_item.ident);
1220         match trait_item.kind {
1221             ty::AssocKind::Const | ty::AssocKind::Fn => {
1222                 self.encode_item_type(def_id);
1223             }
1224             ty::AssocKind::Type => {
1225                 if trait_item.defaultness.has_value() {
1226                     self.encode_item_type(def_id);
1227                 }
1228             }
1229         }
1230         if trait_item.kind == ty::AssocKind::Fn {
1231             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1232         }
1233     }
1234
1235     fn encode_info_for_impl_item(&mut self, def_id: DefId) {
1236         debug!("EncodeContext::encode_info_for_impl_item({:?})", def_id);
1237         let tcx = self.tcx;
1238
1239         let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
1240         let impl_item = self.tcx.associated_item(def_id);
1241
1242         let container = match impl_item.defaultness {
1243             hir::Defaultness::Default { has_value: true } => AssocContainer::ImplDefault,
1244             hir::Defaultness::Final => AssocContainer::ImplFinal,
1245             hir::Defaultness::Default { has_value: false } => {
1246                 span_bug!(ast_item.span, "impl items always have values (currently)")
1247             }
1248         };
1249
1250         match impl_item.kind {
1251             ty::AssocKind::Const => {
1252                 if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
1253                     let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
1254                     let const_data = self.encode_rendered_const_for_body(body_id);
1255
1256                     record!(self.tables.kind[def_id] <- EntryKind::AssocConst(container));
1257                     record!(self.tables.mir_const_qualif[def_id] <- qualifs);
1258                     record!(self.tables.rendered_const[def_id] <- const_data);
1259                 } else {
1260                     bug!()
1261                 }
1262             }
1263             ty::AssocKind::Fn => {
1264                 let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() };
1265                 record!(self.tables.asyncness[def_id] <- sig.header.asyncness);
1266                 record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
1267                 // Can be inside `impl const Trait`, so using sig.header.constness is not reliable
1268                 let constness = if self.tcx.is_const_fn_raw(def_id) {
1269                     hir::Constness::Const
1270                 } else {
1271                     hir::Constness::NotConst
1272                 };
1273                 record!(self.tables.impl_constness[def_id] <- constness);
1274                 record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData {
1275                     container,
1276                     has_self: impl_item.fn_has_self_parameter,
1277                 })));
1278             }
1279             ty::AssocKind::Type => {
1280                 record!(self.tables.kind[def_id] <- EntryKind::AssocType(container));
1281             }
1282         }
1283         self.encode_ident_span(def_id, impl_item.ident(self.tcx));
1284         self.encode_item_type(def_id);
1285         if let Some(trait_item_def_id) = impl_item.trait_item_def_id {
1286             record!(self.tables.trait_item_def_id[def_id] <- trait_item_def_id);
1287         }
1288         if impl_item.kind == ty::AssocKind::Fn {
1289             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1290         }
1291     }
1292
1293     fn encode_mir(&mut self) {
1294         if self.is_proc_macro {
1295             return;
1296         }
1297
1298         let keys_and_jobs = self
1299             .tcx
1300             .mir_keys(())
1301             .iter()
1302             .filter_map(|&def_id| {
1303                 let (encode_const, encode_opt) = should_encode_mir(self.tcx, def_id);
1304                 if encode_const || encode_opt {
1305                     Some((def_id, encode_const, encode_opt))
1306                 } else {
1307                     None
1308                 }
1309             })
1310             .collect::<Vec<_>>();
1311         for (def_id, encode_const, encode_opt) in keys_and_jobs.into_iter() {
1312             debug_assert!(encode_const || encode_opt);
1313
1314             debug!("EntryBuilder::encode_mir({:?})", def_id);
1315             if encode_opt {
1316                 record!(self.tables.optimized_mir[def_id.to_def_id()] <- self.tcx.optimized_mir(def_id));
1317             }
1318             if encode_const {
1319                 record!(self.tables.mir_for_ctfe[def_id.to_def_id()] <- self.tcx.mir_for_ctfe(def_id));
1320
1321                 // FIXME(generic_const_exprs): this feels wrong to have in `encode_mir`
1322                 let abstract_const = self.tcx.thir_abstract_const(def_id);
1323                 if let Ok(Some(abstract_const)) = abstract_const {
1324                     record!(self.tables.thir_abstract_const[def_id.to_def_id()] <- abstract_const);
1325                 }
1326             }
1327             record!(self.tables.promoted_mir[def_id.to_def_id()] <- self.tcx.promoted_mir(def_id));
1328
1329             let instance =
1330                 ty::InstanceDef::Item(ty::WithOptConstParam::unknown(def_id.to_def_id()));
1331             let unused = self.tcx.unused_generic_params(instance);
1332             if !unused.is_empty() {
1333                 record!(self.tables.unused_generic_params[def_id.to_def_id()] <- unused);
1334             }
1335         }
1336     }
1337
1338     fn encode_stability(&mut self, def_id: DefId) {
1339         debug!("EncodeContext::encode_stability({:?})", def_id);
1340
1341         // The query lookup can take a measurable amount of time in crates with many items. Check if
1342         // the stability attributes are even enabled before using their queries.
1343         if self.feat.staged_api || self.tcx.sess.opts.debugging_opts.force_unstable_if_unmarked {
1344             if let Some(stab) = self.tcx.lookup_stability(def_id) {
1345                 record!(self.tables.lookup_stability[def_id] <- stab)
1346             }
1347         }
1348     }
1349
1350     fn encode_const_stability(&mut self, def_id: DefId) {
1351         debug!("EncodeContext::encode_const_stability({:?})", def_id);
1352
1353         // The query lookup can take a measurable amount of time in crates with many items. Check if
1354         // the stability attributes are even enabled before using their queries.
1355         if self.feat.staged_api || self.tcx.sess.opts.debugging_opts.force_unstable_if_unmarked {
1356             if let Some(stab) = self.tcx.lookup_const_stability(def_id) {
1357                 record!(self.tables.lookup_const_stability[def_id] <- stab)
1358             }
1359         }
1360     }
1361
1362     fn encode_deprecation(&mut self, def_id: DefId) {
1363         debug!("EncodeContext::encode_deprecation({:?})", def_id);
1364         if let Some(depr) = self.tcx.lookup_deprecation(def_id) {
1365             record!(self.tables.lookup_deprecation_entry[def_id] <- depr);
1366         }
1367     }
1368
1369     fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> String {
1370         let hir = self.tcx.hir();
1371         let body = hir.body(body_id);
1372         rustc_hir_pretty::to_string(&(&hir as &dyn intravisit::Map<'_>), |s| {
1373             s.print_expr(&body.value)
1374         })
1375     }
1376
1377     fn encode_info_for_item(&mut self, def_id: DefId, item: &'tcx hir::Item<'tcx>) {
1378         let tcx = self.tcx;
1379
1380         debug!("EncodeContext::encode_info_for_item({:?})", def_id);
1381
1382         self.encode_ident_span(def_id, item.ident);
1383
1384         let entry_kind = match item.kind {
1385             hir::ItemKind::Static(..) => EntryKind::Static,
1386             hir::ItemKind::Const(_, body_id) => {
1387                 let qualifs = self.tcx.at(item.span).mir_const_qualif(def_id);
1388                 let const_data = self.encode_rendered_const_for_body(body_id);
1389                 record!(self.tables.mir_const_qualif[def_id] <- qualifs);
1390                 record!(self.tables.rendered_const[def_id] <- const_data);
1391                 EntryKind::Const
1392             }
1393             hir::ItemKind::Fn(ref sig, .., body) => {
1394                 record!(self.tables.asyncness[def_id] <- sig.header.asyncness);
1395                 record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body));
1396                 record!(self.tables.impl_constness[def_id] <- sig.header.constness);
1397                 EntryKind::Fn
1398             }
1399             hir::ItemKind::Macro(ref macro_def, _) => {
1400                 EntryKind::MacroDef(self.lazy(&*macro_def.body), macro_def.macro_rules)
1401             }
1402             hir::ItemKind::Mod(ref m) => {
1403                 return self.encode_info_for_mod(item.def_id, m);
1404             }
1405             hir::ItemKind::ForeignMod { .. } => EntryKind::ForeignMod,
1406             hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
1407             hir::ItemKind::TyAlias(..) => EntryKind::Type,
1408             hir::ItemKind::OpaqueTy(..) => {
1409                 self.encode_explicit_item_bounds(def_id);
1410                 EntryKind::OpaqueTy
1411             }
1412             hir::ItemKind::Enum(..) => {
1413                 let adt_def = self.tcx.adt_def(def_id);
1414                 record!(self.tables.repr_options[def_id] <- adt_def.repr());
1415                 EntryKind::Enum
1416             }
1417             hir::ItemKind::Struct(ref struct_def, _) => {
1418                 let adt_def = self.tcx.adt_def(def_id);
1419                 record!(self.tables.repr_options[def_id] <- adt_def.repr());
1420
1421                 // Encode def_ids for each field and method
1422                 // for methods, write all the stuff get_trait_method
1423                 // needs to know
1424                 let ctor = struct_def
1425                     .ctor_hir_id()
1426                     .map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index);
1427
1428                 let variant = adt_def.non_enum_variant();
1429                 EntryKind::Struct(self.lazy(VariantData {
1430                     ctor_kind: variant.ctor_kind,
1431                     discr: variant.discr,
1432                     ctor,
1433                     is_non_exhaustive: variant.is_field_list_non_exhaustive(),
1434                 }))
1435             }
1436             hir::ItemKind::Union(..) => {
1437                 let adt_def = self.tcx.adt_def(def_id);
1438                 record!(self.tables.repr_options[def_id] <- adt_def.repr());
1439
1440                 let variant = adt_def.non_enum_variant();
1441                 EntryKind::Union(self.lazy(VariantData {
1442                     ctor_kind: variant.ctor_kind,
1443                     discr: variant.discr,
1444                     ctor: None,
1445                     is_non_exhaustive: variant.is_field_list_non_exhaustive(),
1446                 }))
1447             }
1448             hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
1449                 record!(self.tables.impl_defaultness[def_id] <- defaultness);
1450                 record!(self.tables.impl_constness[def_id] <- constness);
1451
1452                 let trait_ref = self.tcx.impl_trait_ref(def_id);
1453                 if let Some(trait_ref) = trait_ref {
1454                     let trait_def = self.tcx.trait_def(trait_ref.def_id);
1455                     if let Some(mut an) = trait_def.ancestors(self.tcx, def_id).ok() {
1456                         if let Some(specialization_graph::Node::Impl(parent)) = an.nth(1) {
1457                             record!(self.tables.impl_parent[def_id] <- parent);
1458                         }
1459                     }
1460
1461                     // if this is an impl of `CoerceUnsized`, create its
1462                     // "unsized info", else just store None
1463                     if Some(trait_ref.def_id) == self.tcx.lang_items().coerce_unsized_trait() {
1464                         let coerce_unsized_info =
1465                             self.tcx.at(item.span).coerce_unsized_info(def_id);
1466                         record!(self.tables.coerce_unsized_info[def_id] <- coerce_unsized_info);
1467                     }
1468                 }
1469
1470                 let polarity = self.tcx.impl_polarity(def_id);
1471                 record!(self.tables.impl_polarity[def_id] <- polarity);
1472
1473                 EntryKind::Impl
1474             }
1475             hir::ItemKind::Trait(..) => {
1476                 let trait_def = self.tcx.trait_def(def_id);
1477                 record!(self.tables.trait_def[def_id] <- trait_def);
1478
1479                 EntryKind::Trait
1480             }
1481             hir::ItemKind::TraitAlias(..) => {
1482                 let trait_def = self.tcx.trait_def(def_id);
1483                 record!(self.tables.trait_def[def_id] <- trait_def);
1484
1485                 EntryKind::TraitAlias
1486             }
1487             hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {
1488                 bug!("cannot encode info for item {:?}", item)
1489             }
1490         };
1491         record!(self.tables.kind[def_id] <- entry_kind);
1492         // FIXME(eddyb) there should be a nicer way to do this.
1493         match item.kind {
1494             hir::ItemKind::Enum(..) => record!(self.tables.children[def_id] <-
1495                 self.tcx.adt_def(def_id).variants().iter().map(|v| {
1496                     assert!(v.def_id.is_local());
1497                     v.def_id.index
1498                 })
1499             ),
1500             hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => {
1501                 record!(self.tables.children[def_id] <-
1502                     self.tcx.adt_def(def_id).non_enum_variant().fields.iter().map(|f| {
1503                         assert!(f.did.is_local());
1504                         f.did.index
1505                     })
1506                 )
1507             }
1508             hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => {
1509                 let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
1510                 record!(self.tables.children[def_id] <-
1511                     associated_item_def_ids.iter().map(|&def_id| {
1512                         assert!(def_id.is_local());
1513                         def_id.index
1514                     })
1515                 );
1516             }
1517             _ => {}
1518         }
1519         match item.kind {
1520             hir::ItemKind::Static(..)
1521             | hir::ItemKind::Const(..)
1522             | hir::ItemKind::Fn(..)
1523             | hir::ItemKind::TyAlias(..)
1524             | hir::ItemKind::OpaqueTy(..)
1525             | hir::ItemKind::Enum(..)
1526             | hir::ItemKind::Struct(..)
1527             | hir::ItemKind::Union(..)
1528             | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id),
1529             _ => {}
1530         }
1531         if let hir::ItemKind::Fn(..) = item.kind {
1532             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1533         }
1534         if let hir::ItemKind::Impl { .. } = item.kind {
1535             if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) {
1536                 record!(self.tables.impl_trait_ref[def_id] <- trait_ref);
1537             }
1538         }
1539     }
1540
1541     fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, encode_type: bool) {
1542         record!(self.tables.kind[def_id] <- kind);
1543         if encode_type {
1544             self.encode_item_type(def_id);
1545         }
1546     }
1547
1548     fn encode_info_for_closure(&mut self, hir_id: hir::HirId) {
1549         let def_id = self.tcx.hir().local_def_id(hir_id);
1550         debug!("EncodeContext::encode_info_for_closure({:?})", def_id);
1551
1552         // NOTE(eddyb) `tcx.type_of(def_id)` isn't used because it's fully generic,
1553         // including on the signature, which is inferred in `typeck.
1554         let ty = self.tcx.typeck(def_id).node_type(hir_id);
1555
1556         match ty.kind() {
1557             ty::Generator(..) => {
1558                 let data = self.tcx.generator_kind(def_id).unwrap();
1559                 record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Generator);
1560                 record!(self.tables.generator_kind[def_id.to_def_id()] <- data);
1561             }
1562
1563             ty::Closure(..) => {
1564                 record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Closure);
1565             }
1566
1567             _ => bug!("closure that is neither generator nor closure"),
1568         }
1569         self.encode_item_type(def_id.to_def_id());
1570         if let ty::Closure(def_id, substs) = *ty.kind() {
1571             record!(self.tables.fn_sig[def_id] <- substs.as_closure().sig());
1572         }
1573     }
1574
1575     fn encode_info_for_anon_const(&mut self, id: hir::HirId) {
1576         let def_id = self.tcx.hir().local_def_id(id);
1577         debug!("EncodeContext::encode_info_for_anon_const({:?})", def_id);
1578         let body_id = self.tcx.hir().body_owned_by(id);
1579         let const_data = self.encode_rendered_const_for_body(body_id);
1580         let qualifs = self.tcx.mir_const_qualif(def_id);
1581
1582         record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::AnonConst);
1583         record!(self.tables.mir_const_qualif[def_id.to_def_id()] <- qualifs);
1584         record!(self.tables.rendered_const[def_id.to_def_id()] <- const_data);
1585         self.encode_item_type(def_id.to_def_id());
1586     }
1587
1588     fn encode_native_libraries(&mut self) -> Lazy<[NativeLib]> {
1589         empty_proc_macro!(self);
1590         let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
1591         self.lazy(used_libraries.iter())
1592     }
1593
1594     fn encode_foreign_modules(&mut self) -> Lazy<[ForeignModule]> {
1595         empty_proc_macro!(self);
1596         let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE);
1597         self.lazy(foreign_modules.iter().map(|(_, m)| m).cloned())
1598     }
1599
1600     fn encode_hygiene(&mut self) -> (SyntaxContextTable, ExpnDataTable, ExpnHashTable) {
1601         let mut syntax_contexts: TableBuilder<_, _> = Default::default();
1602         let mut expn_data_table: TableBuilder<_, _> = Default::default();
1603         let mut expn_hash_table: TableBuilder<_, _> = Default::default();
1604
1605         let _: Result<(), !> = self.hygiene_ctxt.encode(
1606             &mut (&mut *self, &mut syntax_contexts, &mut expn_data_table, &mut expn_hash_table),
1607             |(this, syntax_contexts, _, _), index, ctxt_data| {
1608                 syntax_contexts.set(index, this.lazy(ctxt_data));
1609                 Ok(())
1610             },
1611             |(this, _, expn_data_table, expn_hash_table), index, expn_data, hash| {
1612                 if let Some(index) = index.as_local() {
1613                     expn_data_table.set(index.as_raw(), this.lazy(expn_data));
1614                     expn_hash_table.set(index.as_raw(), this.lazy(hash));
1615                 }
1616                 Ok(())
1617             },
1618         );
1619
1620         (
1621             syntax_contexts.encode(&mut self.opaque),
1622             expn_data_table.encode(&mut self.opaque),
1623             expn_hash_table.encode(&mut self.opaque),
1624         )
1625     }
1626
1627     fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
1628         let is_proc_macro = self.tcx.sess.crate_types().contains(&CrateType::ProcMacro);
1629         if is_proc_macro {
1630             let tcx = self.tcx;
1631             let hir = tcx.hir();
1632
1633             let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index;
1634             let stability = tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX));
1635             let macros =
1636                 self.lazy(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index));
1637             let spans = self.tcx.sess.parse_sess.proc_macro_quoted_spans();
1638             for (i, span) in spans.into_iter().enumerate() {
1639                 let span = self.lazy(span);
1640                 self.tables.proc_macro_quoted_spans.set(i, span);
1641             }
1642
1643             record!(self.tables.opt_def_kind[LOCAL_CRATE.as_def_id()] <- DefKind::Mod);
1644             record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));
1645             record!(self.tables.attributes[LOCAL_CRATE.as_def_id()] <- tcx.get_attrs(LOCAL_CRATE.as_def_id()));
1646             record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- tcx.visibility(LOCAL_CRATE.as_def_id()));
1647             if let Some(stability) = stability {
1648                 record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability);
1649             }
1650             self.encode_deprecation(LOCAL_CRATE.as_def_id());
1651
1652             // Normally, this information is encoded when we walk the items
1653             // defined in this crate. However, we skip doing that for proc-macro crates,
1654             // so we manually encode just the information that we need
1655             for &proc_macro in &tcx.resolutions(()).proc_macros {
1656                 let id = proc_macro;
1657                 let proc_macro = hir.local_def_id_to_hir_id(proc_macro);
1658                 let mut name = hir.name(proc_macro);
1659                 let span = hir.span(proc_macro);
1660                 // Proc-macros may have attributes like `#[allow_internal_unstable]`,
1661                 // so downstream crates need access to them.
1662                 let attrs = hir.attrs(proc_macro);
1663                 let macro_kind = if tcx.sess.contains_name(attrs, sym::proc_macro) {
1664                     MacroKind::Bang
1665                 } else if tcx.sess.contains_name(attrs, sym::proc_macro_attribute) {
1666                     MacroKind::Attr
1667                 } else if let Some(attr) = tcx.sess.find_by_name(attrs, sym::proc_macro_derive) {
1668                     // This unwrap chain should have been checked by the proc-macro harness.
1669                     name = attr.meta_item_list().unwrap()[0]
1670                         .meta_item()
1671                         .unwrap()
1672                         .ident()
1673                         .unwrap()
1674                         .name;
1675                     MacroKind::Derive
1676                 } else {
1677                     bug!("Unknown proc-macro type for item {:?}", id);
1678                 };
1679
1680                 let mut def_key = self.tcx.hir().def_key(id);
1681                 def_key.disambiguated_data.data = DefPathData::MacroNs(name);
1682
1683                 let def_id = id.to_def_id();
1684                 record!(self.tables.opt_def_kind[def_id] <- DefKind::Macro(macro_kind));
1685                 record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind));
1686                 record!(self.tables.attributes[def_id] <- attrs);
1687                 record!(self.tables.def_keys[def_id] <- def_key);
1688                 record!(self.tables.def_ident_span[def_id] <- span);
1689                 record!(self.tables.def_span[def_id] <- span);
1690                 record!(self.tables.visibility[def_id] <- ty::Visibility::Public);
1691                 if let Some(stability) = stability {
1692                     record!(self.tables.lookup_stability[def_id] <- stability);
1693                 }
1694             }
1695
1696             Some(ProcMacroData { proc_macro_decls_static, stability, macros })
1697         } else {
1698             None
1699         }
1700     }
1701
1702     fn encode_crate_deps(&mut self) -> Lazy<[CrateDep]> {
1703         empty_proc_macro!(self);
1704
1705         let deps = self
1706             .tcx
1707             .crates(())
1708             .iter()
1709             .map(|&cnum| {
1710                 let dep = CrateDep {
1711                     name: self.tcx.crate_name(cnum),
1712                     hash: self.tcx.crate_hash(cnum),
1713                     host_hash: self.tcx.crate_host_hash(cnum),
1714                     kind: self.tcx.dep_kind(cnum),
1715                     extra_filename: self.tcx.extra_filename(cnum).clone(),
1716                 };
1717                 (cnum, dep)
1718             })
1719             .collect::<Vec<_>>();
1720
1721         {
1722             // Sanity-check the crate numbers
1723             let mut expected_cnum = 1;
1724             for &(n, _) in &deps {
1725                 assert_eq!(n, CrateNum::new(expected_cnum));
1726                 expected_cnum += 1;
1727             }
1728         }
1729
1730         // We're just going to write a list of crate 'name-hash-version's, with
1731         // the assumption that they are numbered 1 to n.
1732         // FIXME (#2166): This is not nearly enough to support correct versioning
1733         // but is enough to get transitive crate dependencies working.
1734         self.lazy(deps.iter().map(|&(_, ref dep)| dep))
1735     }
1736
1737     fn encode_lib_features(&mut self) -> Lazy<[(Symbol, Option<Symbol>)]> {
1738         empty_proc_macro!(self);
1739         let tcx = self.tcx;
1740         let lib_features = tcx.lib_features(());
1741         self.lazy(lib_features.to_vec())
1742     }
1743
1744     fn encode_diagnostic_items(&mut self) -> Lazy<[(Symbol, DefIndex)]> {
1745         empty_proc_macro!(self);
1746         let tcx = self.tcx;
1747         let diagnostic_items = &tcx.diagnostic_items(LOCAL_CRATE).name_to_id;
1748         self.lazy(diagnostic_items.iter().map(|(&name, def_id)| (name, def_id.index)))
1749     }
1750
1751     fn encode_lang_items(&mut self) -> Lazy<[(DefIndex, usize)]> {
1752         empty_proc_macro!(self);
1753         let tcx = self.tcx;
1754         let lang_items = tcx.lang_items();
1755         let lang_items = lang_items.items().iter();
1756         self.lazy(lang_items.enumerate().filter_map(|(i, &opt_def_id)| {
1757             if let Some(def_id) = opt_def_id {
1758                 if def_id.is_local() {
1759                     return Some((def_id.index, i));
1760                 }
1761             }
1762             None
1763         }))
1764     }
1765
1766     fn encode_lang_items_missing(&mut self) -> Lazy<[lang_items::LangItem]> {
1767         empty_proc_macro!(self);
1768         let tcx = self.tcx;
1769         self.lazy(&tcx.lang_items().missing)
1770     }
1771
1772     fn encode_traits(&mut self) -> Lazy<[DefIndex]> {
1773         empty_proc_macro!(self);
1774         self.lazy(self.tcx.traits_in_crate(LOCAL_CRATE).iter().map(|def_id| def_id.index))
1775     }
1776
1777     /// Encodes an index, mapping each trait to its (local) implementations.
1778     fn encode_impls(&mut self) -> Lazy<[TraitImpls]> {
1779         debug!("EncodeContext::encode_traits_and_impls()");
1780         empty_proc_macro!(self);
1781         let tcx = self.tcx;
1782         let mut visitor = ImplsVisitor { tcx, impls: FxHashMap::default() };
1783         tcx.hir().visit_all_item_likes(&mut visitor);
1784
1785         let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
1786
1787         // Bring everything into deterministic order for hashing
1788         all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id));
1789
1790         let all_impls: Vec<_> = all_impls
1791             .into_iter()
1792             .map(|(trait_def_id, mut impls)| {
1793                 // Bring everything into deterministic order for hashing
1794                 impls.sort_by_cached_key(|&(index, _)| {
1795                     tcx.hir().def_path_hash(LocalDefId { local_def_index: index })
1796                 });
1797
1798                 TraitImpls {
1799                     trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
1800                     impls: self.lazy(&impls),
1801                 }
1802             })
1803             .collect();
1804
1805         self.lazy(&all_impls)
1806     }
1807
1808     fn encode_incoherent_impls(&mut self) -> Lazy<[IncoherentImpls]> {
1809         debug!("EncodeContext::encode_traits_and_impls()");
1810         empty_proc_macro!(self);
1811         let tcx = self.tcx;
1812         let mut ctx = tcx.create_stable_hashing_context();
1813         let mut all_impls: Vec<_> = tcx.crate_inherent_impls(()).incoherent_impls.iter().collect();
1814         all_impls.sort_by_cached_key(|&(&simp, _)| {
1815             let mut hasher = StableHasher::new();
1816             simp.hash_stable(&mut ctx, &mut hasher);
1817             hasher.finish::<Fingerprint>();
1818         });
1819         let all_impls: Vec<_> = all_impls
1820             .into_iter()
1821             .map(|(&simp, impls)| {
1822                 let mut impls: Vec<_> =
1823                     impls.into_iter().map(|def_id| def_id.local_def_index).collect();
1824                 impls.sort_by_cached_key(|&local_def_index| {
1825                     tcx.hir().def_path_hash(LocalDefId { local_def_index })
1826                 });
1827
1828                 IncoherentImpls { self_ty: simp, impls: self.lazy(impls) }
1829             })
1830             .collect();
1831
1832         self.lazy(&all_impls)
1833     }
1834
1835     // Encodes all symbols exported from this crate into the metadata.
1836     //
1837     // This pass is seeded off the reachability list calculated in the
1838     // middle::reachable module but filters out items that either don't have a
1839     // symbol associated with them (they weren't translated) or if they're an FFI
1840     // definition (as that's not defined in this crate).
1841     fn encode_exported_symbols(
1842         &mut self,
1843         exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportLevel)],
1844     ) -> Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]> {
1845         empty_proc_macro!(self);
1846         // The metadata symbol name is special. It should not show up in
1847         // downstream crates.
1848         let metadata_symbol_name = SymbolName::new(self.tcx, &metadata_symbol_name(self.tcx));
1849
1850         self.lazy(
1851             exported_symbols
1852                 .iter()
1853                 .filter(|&&(ref exported_symbol, _)| match *exported_symbol {
1854                     ExportedSymbol::NoDefId(symbol_name) => symbol_name != metadata_symbol_name,
1855                     _ => true,
1856                 })
1857                 .cloned(),
1858         )
1859     }
1860
1861     fn encode_dylib_dependency_formats(&mut self) -> Lazy<[Option<LinkagePreference>]> {
1862         empty_proc_macro!(self);
1863         let formats = self.tcx.dependency_formats(());
1864         for (ty, arr) in formats.iter() {
1865             if *ty != CrateType::Dylib {
1866                 continue;
1867             }
1868             return self.lazy(arr.iter().map(|slot| match *slot {
1869                 Linkage::NotLinked | Linkage::IncludedFromDylib => None,
1870
1871                 Linkage::Dynamic => Some(LinkagePreference::RequireDynamic),
1872                 Linkage::Static => Some(LinkagePreference::RequireStatic),
1873             }));
1874         }
1875         Lazy::empty()
1876     }
1877
1878     fn encode_info_for_foreign_item(&mut self, def_id: DefId, nitem: &hir::ForeignItem<'_>) {
1879         let tcx = self.tcx;
1880
1881         debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id);
1882
1883         match nitem.kind {
1884             hir::ForeignItemKind::Fn(_, ref names, _) => {
1885                 record!(self.tables.asyncness[def_id] <- hir::IsAsync::NotAsync);
1886                 record!(self.tables.fn_arg_names[def_id] <- *names);
1887                 let constness = if self.tcx.is_const_fn_raw(def_id) {
1888                     hir::Constness::Const
1889                 } else {
1890                     hir::Constness::NotConst
1891                 };
1892                 record!(self.tables.impl_constness[def_id] <- constness);
1893                 record!(self.tables.kind[def_id] <- EntryKind::ForeignFn);
1894             }
1895             hir::ForeignItemKind::Static(..) => {
1896                 record!(self.tables.kind[def_id] <- EntryKind::ForeignStatic);
1897             }
1898             hir::ForeignItemKind::Type => {
1899                 record!(self.tables.kind[def_id] <- EntryKind::ForeignType);
1900             }
1901         }
1902         self.encode_ident_span(def_id, nitem.ident);
1903         self.encode_item_type(def_id);
1904         if let hir::ForeignItemKind::Fn(..) = nitem.kind {
1905             record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
1906         }
1907     }
1908 }
1909
1910 // FIXME(eddyb) make metadata encoding walk over all definitions, instead of HIR.
1911 impl<'a, 'tcx> Visitor<'tcx> for EncodeContext<'a, 'tcx> {
1912     type NestedFilter = nested_filter::OnlyBodies;
1913
1914     fn nested_visit_map(&mut self) -> Self::Map {
1915         self.tcx.hir()
1916     }
1917     fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
1918         intravisit::walk_expr(self, ex);
1919         self.encode_info_for_expr(ex);
1920     }
1921     fn visit_anon_const(&mut self, c: &'tcx AnonConst) {
1922         intravisit::walk_anon_const(self, c);
1923         self.encode_info_for_anon_const(c.hir_id);
1924     }
1925     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
1926         intravisit::walk_item(self, item);
1927         match item.kind {
1928             hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => {} // ignore these
1929             _ => self.encode_info_for_item(item.def_id.to_def_id(), item),
1930         }
1931         self.encode_addl_info_for_item(item);
1932     }
1933     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem<'tcx>) {
1934         intravisit::walk_foreign_item(self, ni);
1935         self.encode_info_for_foreign_item(ni.def_id.to_def_id(), ni);
1936     }
1937     fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
1938         intravisit::walk_generics(self, generics);
1939         self.encode_info_for_generics(generics);
1940     }
1941 }
1942
1943 impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
1944     fn encode_fields(&mut self, adt_def: ty::AdtDef<'tcx>) {
1945         for (variant_index, variant) in adt_def.variants().iter_enumerated() {
1946             for (field_index, _field) in variant.fields.iter().enumerate() {
1947                 self.encode_field(adt_def, variant_index, field_index);
1948             }
1949         }
1950     }
1951
1952     fn encode_info_for_generics(&mut self, generics: &hir::Generics<'tcx>) {
1953         for param in generics.params {
1954             let def_id = self.tcx.hir().local_def_id(param.hir_id);
1955             match param.kind {
1956                 GenericParamKind::Lifetime { .. } => continue,
1957                 GenericParamKind::Type { default, .. } => {
1958                     self.encode_info_for_generic_param(
1959                         def_id.to_def_id(),
1960                         EntryKind::TypeParam,
1961                         default.is_some(),
1962                     );
1963                 }
1964                 GenericParamKind::Const { ref default, .. } => {
1965                     let def_id = def_id.to_def_id();
1966                     self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true);
1967                     if default.is_some() {
1968                         record!(self.tables.const_param_default[def_id] <- self.tcx.const_param_default(def_id))
1969                     }
1970                 }
1971             }
1972         }
1973     }
1974
1975     fn encode_info_for_expr(&mut self, expr: &hir::Expr<'_>) {
1976         if let hir::ExprKind::Closure(..) = expr.kind {
1977             self.encode_info_for_closure(expr.hir_id);
1978         }
1979     }
1980
1981     fn encode_ident_span(&mut self, def_id: DefId, ident: Ident) {
1982         record!(self.tables.def_ident_span[def_id] <- ident.span);
1983     }
1984
1985     /// In some cases, along with the item itself, we also
1986     /// encode some sub-items. Usually we want some info from the item
1987     /// so it's easier to do that here then to wait until we would encounter
1988     /// normally in the visitor walk.
1989     fn encode_addl_info_for_item(&mut self, item: &hir::Item<'_>) {
1990         match item.kind {
1991             hir::ItemKind::Static(..)
1992             | hir::ItemKind::Const(..)
1993             | hir::ItemKind::Fn(..)
1994             | hir::ItemKind::Macro(..)
1995             | hir::ItemKind::Mod(..)
1996             | hir::ItemKind::ForeignMod { .. }
1997             | hir::ItemKind::GlobalAsm(..)
1998             | hir::ItemKind::ExternCrate(..)
1999             | hir::ItemKind::Use(..)
2000             | hir::ItemKind::TyAlias(..)
2001             | hir::ItemKind::OpaqueTy(..)
2002             | hir::ItemKind::TraitAlias(..) => {
2003                 // no sub-item recording needed in these cases
2004             }
2005             hir::ItemKind::Enum(..) => {
2006                 let def = self.tcx.adt_def(item.def_id.to_def_id());
2007                 self.encode_fields(def);
2008
2009                 for (i, variant) in def.variants().iter_enumerated() {
2010                     self.encode_enum_variant_info(def, i);
2011
2012                     if let Some(_ctor_def_id) = variant.ctor_def_id {
2013                         self.encode_enum_variant_ctor(def, i);
2014                     }
2015                 }
2016             }
2017             hir::ItemKind::Struct(ref struct_def, _) => {
2018                 let def = self.tcx.adt_def(item.def_id.to_def_id());
2019                 self.encode_fields(def);
2020
2021                 // If the struct has a constructor, encode it.
2022                 if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
2023                     let ctor_def_id = self.tcx.hir().local_def_id(ctor_hir_id);
2024                     self.encode_struct_ctor(def, ctor_def_id.to_def_id());
2025                 }
2026             }
2027             hir::ItemKind::Union(..) => {
2028                 let def = self.tcx.adt_def(item.def_id.to_def_id());
2029                 self.encode_fields(def);
2030             }
2031             hir::ItemKind::Impl { .. } => {
2032                 for &trait_item_def_id in
2033                     self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
2034                 {
2035                     self.encode_info_for_impl_item(trait_item_def_id);
2036                 }
2037             }
2038             hir::ItemKind::Trait(..) => {
2039                 for &item_def_id in self.tcx.associated_item_def_ids(item.def_id.to_def_id()).iter()
2040                 {
2041                     self.encode_info_for_trait_item(item_def_id);
2042                 }
2043             }
2044         }
2045     }
2046 }
2047
2048 struct ImplsVisitor<'tcx> {
2049     tcx: TyCtxt<'tcx>,
2050     impls: FxHashMap<DefId, Vec<(DefIndex, Option<SimplifiedType>)>>,
2051 }
2052
2053 impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplsVisitor<'tcx> {
2054     fn visit_item(&mut self, item: &hir::Item<'_>) {
2055         match item.kind {
2056             hir::ItemKind::Impl(..) => {
2057                 if let Some(trait_ref) = self.tcx.impl_trait_ref(item.def_id.to_def_id()) {
2058                     let simplified_self_ty = fast_reject::simplify_type(
2059                         self.tcx,
2060                         trait_ref.self_ty(),
2061                         TreatParams::AsPlaceholders,
2062                     );
2063
2064                     self.impls
2065                         .entry(trait_ref.def_id)
2066                         .or_default()
2067                         .push((item.def_id.local_def_index, simplified_self_ty));
2068                 }
2069             }
2070             _ => {}
2071         }
2072     }
2073
2074     fn visit_trait_item(&mut self, _trait_item: &'v hir::TraitItem<'v>) {}
2075
2076     fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem<'v>) {
2077         // handled in `visit_item` above
2078     }
2079
2080     fn visit_foreign_item(&mut self, _foreign_item: &'v hir::ForeignItem<'v>) {}
2081 }
2082
2083 /// Used to prefetch queries which will be needed later by metadata encoding.
2084 /// Only a subset of the queries are actually prefetched to keep this code smaller.
2085 fn prefetch_mir(tcx: TyCtxt<'_>) {
2086     if !tcx.sess.opts.output_types.should_codegen() {
2087         // We won't emit MIR, so don't prefetch it.
2088         return;
2089     }
2090
2091     par_iter(tcx.mir_keys(())).for_each(|&def_id| {
2092         let (encode_const, encode_opt) = should_encode_mir(tcx, def_id);
2093
2094         if encode_const {
2095             tcx.ensure().mir_for_ctfe(def_id);
2096         }
2097         if encode_opt {
2098             tcx.ensure().optimized_mir(def_id);
2099         }
2100         if encode_opt || encode_const {
2101             tcx.ensure().promoted_mir(def_id);
2102         }
2103     })
2104 }
2105
2106 // NOTE(eddyb) The following comment was preserved for posterity, even
2107 // though it's no longer relevant as EBML (which uses nested & tagged
2108 // "documents") was replaced with a scheme that can't go out of bounds.
2109 //
2110 // And here we run into yet another obscure archive bug: in which metadata
2111 // loaded from archives may have trailing garbage bytes. Awhile back one of
2112 // our tests was failing sporadically on the macOS 64-bit builders (both nopt
2113 // and opt) by having ebml generate an out-of-bounds panic when looking at
2114 // metadata.
2115 //
2116 // Upon investigation it turned out that the metadata file inside of an rlib
2117 // (and ar archive) was being corrupted. Some compilations would generate a
2118 // metadata file which would end in a few extra bytes, while other
2119 // compilations would not have these extra bytes appended to the end. These
2120 // extra bytes were interpreted by ebml as an extra tag, so they ended up
2121 // being interpreted causing the out-of-bounds.
2122 //
2123 // The root cause of why these extra bytes were appearing was never
2124 // discovered, and in the meantime the solution we're employing is to insert
2125 // the length of the metadata to the start of the metadata. Later on this
2126 // will allow us to slice the metadata to the precise length that we just
2127 // generated regardless of trailing bytes that end up in it.
2128
2129 #[derive(Encodable, Decodable)]
2130 pub struct EncodedMetadata {
2131     raw_data: Vec<u8>,
2132 }
2133
2134 impl EncodedMetadata {
2135     #[inline]
2136     pub fn new() -> EncodedMetadata {
2137         EncodedMetadata { raw_data: Vec::new() }
2138     }
2139
2140     #[inline]
2141     pub fn raw_data(&self) -> &[u8] {
2142         &self.raw_data
2143     }
2144 }
2145
2146 pub fn encode_metadata(tcx: TyCtxt<'_>) -> EncodedMetadata {
2147     let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata");
2148
2149     // Since encoding metadata is not in a query, and nothing is cached,
2150     // there's no need to do dep-graph tracking for any of it.
2151     tcx.dep_graph.assert_ignored();
2152
2153     join(
2154         || encode_metadata_impl(tcx),
2155         || {
2156             if tcx.sess.threads() == 1 {
2157                 return;
2158             }
2159             // Prefetch some queries used by metadata encoding.
2160             // This is not necessary for correctness, but is only done for performance reasons.
2161             // It can be removed if it turns out to cause trouble or be detrimental to performance.
2162             join(|| prefetch_mir(tcx), || tcx.exported_symbols(LOCAL_CRATE));
2163         },
2164     )
2165     .0
2166 }
2167
2168 fn encode_metadata_impl(tcx: TyCtxt<'_>) -> EncodedMetadata {
2169     let mut encoder = opaque::Encoder::new(vec![]);
2170     encoder.emit_raw_bytes(METADATA_HEADER).unwrap();
2171
2172     // Will be filled with the root position after encoding everything.
2173     encoder.emit_raw_bytes(&[0, 0, 0, 0]).unwrap();
2174
2175     let source_map_files = tcx.sess.source_map().files();
2176     let source_file_cache = (source_map_files[0].clone(), 0);
2177     let required_source_files = Some(GrowableBitSet::with_capacity(source_map_files.len()));
2178     drop(source_map_files);
2179
2180     let hygiene_ctxt = HygieneEncodeContext::default();
2181
2182     let mut ecx = EncodeContext {
2183         opaque: encoder,
2184         tcx,
2185         feat: tcx.features(),
2186         tables: Default::default(),
2187         lazy_state: LazyState::NoNode,
2188         type_shorthands: Default::default(),
2189         predicate_shorthands: Default::default(),
2190         source_file_cache,
2191         interpret_allocs: Default::default(),
2192         required_source_files,
2193         is_proc_macro: tcx.sess.crate_types().contains(&CrateType::ProcMacro),
2194         hygiene_ctxt: &hygiene_ctxt,
2195     };
2196
2197     // Encode the rustc version string in a predictable location.
2198     rustc_version().encode(&mut ecx).unwrap();
2199
2200     // Encode all the entries and extra information in the crate,
2201     // culminating in the `CrateRoot` which points to all of it.
2202     let root = ecx.encode_crate_root();
2203
2204     let mut result = ecx.opaque.into_inner();
2205
2206     // Encode the root position.
2207     let header = METADATA_HEADER.len();
2208     let pos = root.position.get();
2209     result[header + 0] = (pos >> 24) as u8;
2210     result[header + 1] = (pos >> 16) as u8;
2211     result[header + 2] = (pos >> 8) as u8;
2212     result[header + 3] = (pos >> 0) as u8;
2213
2214     // Record metadata size for self-profiling
2215     tcx.prof.artifact_size("crate_metadata", "crate_metadata", result.len() as u64);
2216
2217     EncodedMetadata { raw_data: result }
2218 }
2219
2220 pub fn provide(providers: &mut Providers) {
2221     *providers = Providers {
2222         traits_in_crate: |tcx, cnum| {
2223             assert_eq!(cnum, LOCAL_CRATE);
2224
2225             #[derive(Default)]
2226             struct TraitsVisitor {
2227                 traits: Vec<DefId>,
2228             }
2229             impl ItemLikeVisitor<'_> for TraitsVisitor {
2230                 fn visit_item(&mut self, item: &hir::Item<'_>) {
2231                     if let hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) = item.kind {
2232                         self.traits.push(item.def_id.to_def_id());
2233                     }
2234                 }
2235                 fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {}
2236                 fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {}
2237                 fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {}
2238             }
2239
2240             let mut visitor = TraitsVisitor::default();
2241             tcx.hir().visit_all_item_likes(&mut visitor);
2242             // Bring everything into deterministic order.
2243             visitor.traits.sort_by_cached_key(|&def_id| tcx.def_path_hash(def_id));
2244             tcx.arena.alloc_slice(&visitor.traits)
2245         },
2246
2247         ..*providers
2248     };
2249 }