]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_metadata/src/rmeta/decoder.rs
New upstream version 1.60.0+dfsg1
[rustc.git] / compiler / rustc_metadata / src / rmeta / decoder.rs
CommitLineData
223e47cc
LB
1// Decoding metadata from a single crate's metadata
2
74b04a01 3use crate::creader::CrateMetadataRef;
60c5eb7d 4use crate::rmeta::table::{FixedSizeEncoding, Table};
dfeec247 5use crate::rmeta::*;
9e0c209e 6
3dfed10e 7use rustc_ast as ast;
ba9703b0 8use rustc_attr as attr;
dfeec247 9use rustc_data_structures::captures::Captures;
dfeec247
XL
10use rustc_data_structures::fx::FxHashMap;
11use rustc_data_structures::svh::Svh;
5869c6ff
XL
12use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell};
13use rustc_data_structures::unhash::UnhashMap;
1b1a35ee 14use rustc_errors::ErrorReported;
ba9703b0
XL
15use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
16use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive};
dfeec247
XL
17use rustc_hir as hir;
18use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
3dfed10e 19use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
ba9703b0 20use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
c295e0f8 21use rustc_hir::diagnostic_items::DiagnosticItems;
ba9703b0 22use rustc_hir::lang_items;
dfeec247 23use rustc_index::vec::{Idx, IndexVec};
5099ac24 24use rustc_middle::metadata::ModChild;
ba9703b0
XL
25use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
26use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
3dfed10e 27use rustc_middle::mir::{self, Body, Promoted};
c295e0f8 28use rustc_middle::thir;
ba9703b0 29use rustc_middle::ty::codec::TyDecoder;
a2a8927a 30use rustc_middle::ty::fast_reject::SimplifiedType;
17df50a5 31use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
3dfed10e 32use rustc_serialize::{opaque, Decodable, Decoder};
c295e0f8
XL
33use rustc_session::cstore::{
34 CrateSource, ExternCrate, ForeignModule, LinkagePreference, NativeLib,
35};
ba9703b0 36use rustc_session::Session;
136023e0 37use rustc_span::hygiene::{ExpnIndex, MacroKind};
ba9703b0 38use rustc_span::source_map::{respan, Spanned};
f9f354fc 39use rustc_span::symbol::{sym, Ident, Symbol};
136023e0 40use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP};
9cc50fc6 41
ba9703b0 42use proc_macro::bridge::client::ProcMacro;
c34b1796 43use std::io;
9e0c209e 44use std::mem;
e74abb32 45use std::num::NonZeroUsize;
ba9703b0 46use std::path::Path;
3dfed10e 47use tracing::debug;
223e47cc 48
a2a8927a
XL
49pub(super) use cstore_impl::provide;
50pub use cstore_impl::provide_extern;
3dfed10e 51use rustc_span::hygiene::HygieneDecodeContext;
60c5eb7d
XL
52
53mod cstore_impl;
54
c295e0f8
XL
55/// A reference to the raw binary version of crate metadata.
56/// A `MetadataBlob` internally is just a reference counted pointer to
57/// the actual data, so cloning it is cheap.
58#[derive(Clone)]
59crate struct MetadataBlob(Lrc<MetadataRef>);
60
61// This is needed so we can create an OwningRef into the blob.
62// The data behind a `MetadataBlob` has a stable address because it is
63// contained within an Rc/Arc.
64unsafe impl rustc_data_structures::owning_ref::StableAddress for MetadataBlob {}
65
66// This is needed so we can create an OwningRef into the blob.
67impl std::ops::Deref for MetadataBlob {
68 type Target = [u8];
69
70 #[inline]
71 fn deref(&self) -> &[u8] {
72 &self.0[..]
73 }
74}
60c5eb7d
XL
75
76// A map from external crate numbers (as decoded from some crate file) to
77// local crate numbers (as generated during this session). Each external
78// crate may refer to types in other external crates, and each has their
79// own crate numbers.
80crate type CrateNumMap = IndexVec<CrateNum, CrateNum>;
81
82crate struct CrateMetadata {
83 /// The primary crate data - binary metadata blob.
84 blob: MetadataBlob,
85
86 // --- Some data pre-decoded from the metadata blob, usually for performance ---
60c5eb7d
XL
87 /// Properties of the whole crate.
88 /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this
94222f64 89 /// lifetime is only used behind `Lazy`, and therefore acts like a
60c5eb7d
XL
90 /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
91 /// is being used to decode those values.
92 root: CrateRoot<'static>,
60c5eb7d
XL
93 /// Trait impl data.
94 /// FIXME: Used only from queries and can use query cache,
95 /// so pre-decoding can probably be avoided.
a2a8927a 96 trait_impls: FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<SimplifiedType>)]>>,
60c5eb7d
XL
97 /// Proc macro descriptions for this crate, if it's a proc macro crate.
98 raw_proc_macros: Option<&'static [ProcMacro]>,
99 /// Source maps for code from the crate.
f9f354fc 100 source_map_import_info: OnceCell<Vec<ImportedSourceFile>>,
c295e0f8
XL
101 /// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`.
102 def_path_hash_map: DefPathHashMapRef<'static>,
136023e0
XL
103 /// Likewise for ExpnHash.
104 expn_hash_map: OnceCell<UnhashMap<ExpnHash, ExpnIndex>>,
60c5eb7d
XL
105 /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
106 alloc_decoding_state: AllocDecodingState,
3dfed10e
XL
107 /// Caches decoded `DefKey`s.
108 def_key_cache: Lock<FxHashMap<DefIndex, DefKey>>,
109 /// Caches decoded `DefPathHash`es.
110 def_path_hash_cache: Lock<FxHashMap<DefIndex, DefPathHash>>,
60c5eb7d
XL
111
112 // --- Other significant crate properties ---
60c5eb7d
XL
113 /// ID of this crate, from the current compilation session's point of view.
114 cnum: CrateNum,
115 /// Maps crate IDs as they are were seen from this crate's compilation sessions into
116 /// IDs as they are seen from the current compilation session.
117 cnum_map: CrateNumMap,
118 /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime.
119 dependencies: Lock<Vec<CrateNum>>,
120 /// How to link (or not link) this crate to the currently compiled crate.
3dfed10e 121 dep_kind: Lock<CrateDepKind>,
60c5eb7d 122 /// Filesystem location of this crate.
5099ac24 123 source: Lrc<CrateSource>,
60c5eb7d
XL
124 /// Whether or not this crate should be consider a private dependency
125 /// for purposes of the 'exported_private_dependencies' lint
126 private_dep: bool,
127 /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
128 host_hash: Option<Svh>,
129
3dfed10e
XL
130 /// Additional data used for decoding `HygieneData` (e.g. `SyntaxContext`
131 /// and `ExpnId`).
132 /// Note that we store a `HygieneDecodeContext` for each `CrateMetadat`. This is
133 /// because `SyntaxContext` ids are not globally unique, so we need
134 /// to track which ids we've decoded on a per-crate basis.
135 hygiene_context: HygieneDecodeContext,
136
60c5eb7d 137 // --- Data used only for improving diagnostics ---
60c5eb7d
XL
138 /// Information about the `extern crate` item or path that caused this crate to be loaded.
139 /// If this is `None`, then the crate was injected (e.g., by the allocator).
140 extern_crate: Lock<Option<ExternCrate>>,
141}
142
dfeec247 143/// Holds information about a rustc_span::SourceFile imported from another crate.
60c5eb7d
XL
144/// See `imported_source_files()` for more information.
145struct ImportedSourceFile {
146 /// This SourceFile's byte-offset within the source_map of its original crate
dfeec247 147 original_start_pos: rustc_span::BytePos,
60c5eb7d 148 /// The end of this SourceFile within the source_map of its original crate
dfeec247 149 original_end_pos: rustc_span::BytePos,
60c5eb7d 150 /// The imported SourceFile's representation within the local source_map
dfeec247 151 translated_source_file: Lrc<rustc_span::SourceFile>,
60c5eb7d
XL
152}
153
154pub(super) struct DecodeContext<'a, 'tcx> {
9e0c209e 155 opaque: opaque::Decoder<'a>,
74b04a01 156 cdata: Option<CrateMetadataRef<'a>>,
c295e0f8 157 blob: &'a MetadataBlob,
dc9dc135
XL
158 sess: Option<&'tcx Session>,
159 tcx: Option<TyCtxt<'tcx>>,
c34b1796 160
b7449926
XL
161 // Cache the last used source_file for translating spans as an optimization.
162 last_source_file_index: usize,
223e47cc 163
c30ab7b3 164 lazy_state: LazyState,
0531ce1d 165
94b46f34
XL
166 // Used for decoding interpret::AllocIds in a cached & thread-safe manner.
167 alloc_decoding_session: Option<AllocDecodingSession<'a>>,
223e47cc
LB
168}
169
9e0c209e 170/// Abstract over the various ways one can create metadata decoders.
60c5eb7d 171pub(super) trait Metadata<'a, 'tcx>: Copy {
c295e0f8
XL
172 fn blob(self) -> &'a MetadataBlob;
173
74b04a01 174 fn cdata(self) -> Option<CrateMetadataRef<'a>> {
dfeec247
XL
175 None
176 }
177 fn sess(self) -> Option<&'tcx Session> {
178 None
179 }
180 fn tcx(self) -> Option<TyCtxt<'tcx>> {
181 None
182 }
b039eaaf 183
9e0c209e 184 fn decoder(self, pos: usize) -> DecodeContext<'a, 'tcx> {
476ff2be 185 let tcx = self.tcx();
9e0c209e 186 DecodeContext {
c295e0f8 187 opaque: opaque::Decoder::new(self.blob(), pos),
9e0c209e 188 cdata: self.cdata(),
c295e0f8 189 blob: self.blob(),
476ff2be 190 sess: self.sess().or(tcx.map(|tcx| tcx.sess)),
3b2f2976 191 tcx,
b7449926 192 last_source_file_index: 0,
c30ab7b3 193 lazy_state: LazyState::NoNode,
dfeec247
XL
194 alloc_decoding_session: self
195 .cdata()
74b04a01 196 .map(|cdata| cdata.cdata.alloc_decoding_state.new_decoding_session()),
9e0c209e
SL
197 }
198 }
b039eaaf
SL
199}
200
9e0c209e 201impl<'a, 'tcx> Metadata<'a, 'tcx> for &'a MetadataBlob {
c295e0f8
XL
202 #[inline]
203 fn blob(self) -> &'a MetadataBlob {
204 self
9e0c209e 205 }
223e47cc
LB
206}
207
dc9dc135 208impl<'a, 'tcx> Metadata<'a, 'tcx> for (&'a MetadataBlob, &'tcx Session) {
c295e0f8
XL
209 #[inline]
210 fn blob(self) -> &'a MetadataBlob {
211 self.0
abe05a73
XL
212 }
213
c295e0f8 214 #[inline]
dc9dc135 215 fn sess(self) -> Option<&'tcx Session> {
abe05a73
XL
216 let (_, sess) = self;
217 Some(sess)
218 }
219}
220
5099ac24 221impl<'a, 'tcx> Metadata<'a, 'tcx> for CrateMetadataRef<'a> {
c295e0f8
XL
222 #[inline]
223 fn blob(self) -> &'a MetadataBlob {
5099ac24 224 &self.cdata.blob
c30ab7b3 225 }
c295e0f8 226 #[inline]
74b04a01 227 fn cdata(self) -> Option<CrateMetadataRef<'a>> {
5099ac24 228 Some(self)
c30ab7b3 229 }
a7813a04
XL
230}
231
5099ac24 232impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, &'tcx Session) {
c295e0f8
XL
233 #[inline]
234 fn blob(self) -> &'a MetadataBlob {
5099ac24 235 &self.0.cdata.blob
476ff2be 236 }
c295e0f8 237 #[inline]
74b04a01 238 fn cdata(self) -> Option<CrateMetadataRef<'a>> {
5099ac24 239 Some(self.0)
476ff2be 240 }
c295e0f8 241 #[inline]
dc9dc135 242 fn sess(self) -> Option<&'tcx Session> {
5099ac24 243 Some(self.1)
476ff2be
SL
244 }
245}
246
5099ac24 247impl<'a, 'tcx> Metadata<'a, 'tcx> for (CrateMetadataRef<'a>, TyCtxt<'tcx>) {
c295e0f8
XL
248 #[inline]
249 fn blob(self) -> &'a MetadataBlob {
5099ac24 250 &self.0.cdata.blob
c30ab7b3 251 }
c295e0f8 252 #[inline]
74b04a01 253 fn cdata(self) -> Option<CrateMetadataRef<'a>> {
5099ac24 254 Some(self.0)
c30ab7b3 255 }
c295e0f8 256 #[inline]
dc9dc135 257 fn tcx(self) -> Option<TyCtxt<'tcx>> {
c30ab7b3
SL
258 Some(self.1)
259 }
223e47cc
LB
260}
261
3dfed10e 262impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<T> {
60c5eb7d 263 fn decode<M: Metadata<'a, 'tcx>>(self, metadata: M) -> T {
e74abb32 264 let mut dcx = metadata.decoder(self.position.get());
9e0c209e 265 dcx.lazy_state = LazyState::NodeStart(self.position);
5099ac24 266 T::decode(&mut dcx)
54a0048b
SL
267 }
268}
269
3dfed10e 270impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable<DecodeContext<'a, 'tcx>>> Lazy<[T]> {
60c5eb7d 271 fn decode<M: Metadata<'a, 'tcx>>(
0531ce1d 272 self,
e74abb32 273 metadata: M,
e1599b0c 274 ) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x {
e74abb32 275 let mut dcx = metadata.decoder(self.position.get());
9e0c209e 276 dcx.lazy_state = LazyState::NodeStart(self.position);
5099ac24 277 (0..self.meta).map(move |_| T::decode(&mut dcx))
62682a34
SL
278 }
279}
280
9e0c209e 281impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
c295e0f8 282 #[inline]
e74abb32 283 fn tcx(&self) -> TyCtxt<'tcx> {
c295e0f8
XL
284 debug_assert!(self.tcx.is_some(), "missing TyCtxt in DecodeContext");
285 self.tcx.unwrap()
286 }
287
288 #[inline]
289 pub fn blob(&self) -> &'a MetadataBlob {
290 self.blob
9e0c209e 291 }
223e47cc 292
c295e0f8
XL
293 #[inline]
294 pub fn cdata(&self) -> CrateMetadataRef<'a> {
295 debug_assert!(self.cdata.is_some(), "missing CrateMetadata in DecodeContext");
296 self.cdata.unwrap()
9e0c209e 297 }
a7813a04 298
17df50a5
XL
299 fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
300 if cnum == LOCAL_CRATE { self.cdata().cnum } else { self.cdata().cnum_map[cnum] }
301 }
302
5099ac24
FG
303 fn read_lazy_with_meta<T: ?Sized + LazyMeta>(&mut self, meta: T::Meta) -> Lazy<T> {
304 let distance = self.read_usize();
9e0c209e 305 let position = match self.lazy_state {
e1599b0c 306 LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"),
9e0c209e 307 LazyState::NodeStart(start) => {
e74abb32 308 let start = start.get();
5099ac24
FG
309 assert!(distance <= start);
310 start - distance
9e0c209e 311 }
5099ac24 312 LazyState::Previous(last_pos) => last_pos.get() + distance,
9e0c209e 313 };
5099ac24
FG
314 self.lazy_state = LazyState::Previous(NonZeroUsize::new(position).unwrap());
315 Lazy::from_position_and_meta(NonZeroUsize::new(position).unwrap(), meta)
9e0c209e 316 }
c295e0f8
XL
317
318 #[inline]
319 pub fn read_raw_bytes(&mut self, len: usize) -> &'a [u8] {
320 self.opaque.read_raw_bytes(len)
321 }
223e47cc
LB
322}
323
dc9dc135 324impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
3dfed10e
XL
325 const CLEAR_CROSS_CRATE: bool = true;
326
abe05a73 327 #[inline]
dc9dc135 328 fn tcx(&self) -> TyCtxt<'tcx> {
abe05a73
XL
329 self.tcx.expect("missing TyCtxt in DecodeContext")
330 }
331
332 #[inline]
333 fn peek_byte(&self) -> u8 {
334 self.opaque.data[self.opaque.position()]
9e0c209e 335 }
223e47cc 336
abe05a73
XL
337 #[inline]
338 fn position(&self) -> usize {
339 self.opaque.position()
340 }
223e47cc 341
5099ac24 342 fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
dfeec247 343 where
5099ac24 344 F: FnOnce(&mut Self) -> Ty<'tcx>,
abe05a73
XL
345 {
346 let tcx = self.tcx();
223e47cc 347
17df50a5 348 let key = ty::CReaderCacheKey { cnum: Some(self.cdata().cnum), pos: shorthand };
1a4d82fc 349
f035d41b 350 if let Some(&ty) = tcx.ty_rcache.borrow().get(&key) {
5099ac24 351 return ty;
abe05a73 352 }
223e47cc 353
5099ac24 354 let ty = or_insert_with(self);
f035d41b 355 tcx.ty_rcache.borrow_mut().insert(key, ty);
5099ac24 356 ty
9e0c209e 357 }
62682a34 358
abe05a73 359 fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
dfeec247
XL
360 where
361 F: FnOnce(&mut Self) -> R,
abe05a73
XL
362 {
363 let new_opaque = opaque::Decoder::new(self.opaque.data, pos);
364 let old_opaque = mem::replace(&mut self.opaque, new_opaque);
365 let old_state = mem::replace(&mut self.lazy_state, LazyState::NoNode);
366 let r = f(self);
367 self.opaque = old_opaque;
368 self.lazy_state = old_state;
369 r
370 }
371
5099ac24 372 fn decode_alloc_id(&mut self) -> rustc_middle::mir::interpret::AllocId {
3dfed10e
XL
373 if let Some(alloc_decoding_session) = self.alloc_decoding_session {
374 alloc_decoding_session.decode_alloc_id(self)
375 } else {
376 bug!("Attempting to decode interpret::AllocId without CrateMetadata")
377 }
9e0c209e 378 }
223e47cc
LB
379}
380
3dfed10e 381impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for CrateNum {
5099ac24
FG
382 fn decode(d: &mut DecodeContext<'a, 'tcx>) -> CrateNum {
383 let cnum = CrateNum::from_u32(d.read_u32());
384 d.map_encoded_cnum_to_current(cnum)
9e0c209e 385 }
970d7e83
LB
386}
387
3dfed10e 388impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for DefIndex {
5099ac24
FG
389 fn decode(d: &mut DecodeContext<'a, 'tcx>) -> DefIndex {
390 DefIndex::from_u32(d.read_u32())
e74abb32
XL
391 }
392}
abe05a73 393
136023e0 394impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnIndex {
5099ac24
FG
395 fn decode(d: &mut DecodeContext<'a, 'tcx>) -> ExpnIndex {
396 ExpnIndex::from_u32(d.read_u32())
136023e0
XL
397 }
398}
399
3dfed10e 400impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
5099ac24 401 fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SyntaxContext {
3dfed10e
XL
402 let cdata = decoder.cdata();
403 let sess = decoder.sess.unwrap();
404 let cname = cdata.root.name;
405 rustc_span::hygiene::decode_syntax_context(decoder, &cdata.hygiene_context, |_, id| {
406 debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
5099ac24 407 cdata
3dfed10e
XL
408 .root
409 .syntax_contexts
5099ac24 410 .get(cdata, id)
3dfed10e 411 .unwrap_or_else(|| panic!("Missing SyntaxContext {:?} for crate {:?}", id, cname))
5099ac24 412 .decode((cdata, sess))
3dfed10e 413 })
1a4d82fc
JJ
414 }
415}
416
3dfed10e 417impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
5099ac24 418 fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> ExpnId {
3dfed10e
XL
419 let local_cdata = decoder.cdata();
420 let sess = decoder.sess.unwrap();
0531ce1d 421
5099ac24
FG
422 let cnum = CrateNum::decode(decoder);
423 let index = u32::decode(decoder);
136023e0
XL
424
425 let expn_id = rustc_span::hygiene::decode_expn_id(cnum, index, |expn_id| {
426 let ExpnId { krate: cnum, local_id: index } = expn_id;
427 // Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
428 // are stored in the owning crate, to avoid duplication.
429 debug_assert_ne!(cnum, LOCAL_CRATE);
430 let crate_data = if cnum == local_cdata.cnum {
431 local_cdata
432 } else {
433 local_cdata.cstore.get_crate_data(cnum)
434 };
435 let expn_data = crate_data
436 .root
437 .expn_data
5099ac24 438 .get(crate_data, index)
136023e0 439 .unwrap()
5099ac24 440 .decode((crate_data, sess));
136023e0
XL
441 let expn_hash = crate_data
442 .root
443 .expn_hashes
5099ac24 444 .get(crate_data, index)
136023e0 445 .unwrap()
5099ac24 446 .decode((crate_data, sess));
136023e0
XL
447 (expn_data, expn_hash)
448 });
5099ac24 449 expn_id
0531ce1d
XL
450 }
451}
452
3dfed10e 453impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
5099ac24
FG
454 fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Span {
455 let ctxt = SyntaxContext::decode(decoder);
456 let tag = u8::decode(decoder);
85aaf69f 457
cdc7bbd5 458 if tag == TAG_PARTIAL_SPAN {
5099ac24 459 return DUMMY_SP.with_ctxt(ctxt);
ff7c6d11
XL
460 }
461
ba9703b0 462 debug_assert!(tag == TAG_VALID_SPAN_LOCAL || tag == TAG_VALID_SPAN_FOREIGN);
2c00a5a8 463
5099ac24
FG
464 let lo = BytePos::decode(decoder);
465 let len = BytePos::decode(decoder);
2c00a5a8 466 let hi = lo + len;
ff7c6d11 467
3c0e092e 468 let Some(sess) = decoder.sess else {
abe05a73 469 bug!("Cannot decode Span without Session.")
9e0c209e 470 };
85aaf69f 471
ba9703b0
XL
472 // There are two possibilities here:
473 // 1. This is a 'local span', which is located inside a `SourceFile`
474 // that came from this crate. In this case, we use the source map data
475 // encoded in this crate. This branch should be taken nearly all of the time.
476 // 2. This is a 'foreign span', which is located inside a `SourceFile`
477 // that came from a *different* crate (some crate upstream of the one
478 // whose metadata we're looking at). For example, consider this dependency graph:
479 //
480 // A -> B -> C
481 //
482 // Suppose that we're currently compiling crate A, and start deserializing
483 // metadata from crate B. When we deserialize a Span from crate B's metadata,
484 // there are two posibilites:
485 //
486 // 1. The span references a file from crate B. This makes it a 'local' span,
487 // which means that we can use crate B's serialized source map information.
488 // 2. The span references a file from crate C. This makes it a 'foreign' span,
489 // which means we need to use Crate *C* (not crate B) to determine the source
490 // map information. We only record source map information for a file in the
491 // crate that 'owns' it, so deserializing a Span may require us to look at
492 // a transitive dependency.
493 //
494 // When we encode a foreign span, we adjust its 'lo' and 'high' values
495 // to be based on the *foreign* crate (e.g. crate C), not the crate
496 // we are writing metadata for (e.g. crate B). This allows us to
497 // treat the 'local' and 'foreign' cases almost identically during deserialization:
498 // we can call `imported_source_files` for the proper crate, and binary search
499 // through the returned slice using our span.
500 let imported_source_files = if tag == TAG_VALID_SPAN_LOCAL {
3dfed10e 501 decoder.cdata().imported_source_files(sess)
ba9703b0 502 } else {
f035d41b
XL
503 // When we encode a proc-macro crate, all `Span`s should be encoded
504 // with `TAG_VALID_SPAN_LOCAL`
3dfed10e 505 if decoder.cdata().root.is_proc_macro_crate() {
ba9703b0
XL
506 // Decode `CrateNum` as u32 - using `CrateNum::decode` will ICE
507 // since we don't have `cnum_map` populated.
5099ac24 508 let cnum = u32::decode(decoder);
f035d41b
XL
509 panic!(
510 "Decoding of crate {:?} tried to access proc-macro dep {:?}",
3dfed10e 511 decoder.cdata().root.name,
f035d41b
XL
512 cnum
513 );
ba9703b0
XL
514 }
515 // tag is TAG_VALID_SPAN_FOREIGN, checked by `debug_assert` above
5099ac24 516 let cnum = CrateNum::decode(decoder);
ba9703b0
XL
517 debug!(
518 "SpecializedDecoder<Span>::specialized_decode: loading source files from cnum {:?}",
519 cnum
520 );
521
522 // Decoding 'foreign' spans should be rare enough that it's
523 // not worth it to maintain a per-CrateNum cache for `last_source_file_index`.
524 // We just set it to 0, to ensure that we don't try to access something out
525 // of bounds for our initial 'guess'
3dfed10e 526 decoder.last_source_file_index = 0;
ba9703b0 527
3dfed10e 528 let foreign_data = decoder.cdata().cstore.get_crate_data(cnum);
ba9703b0
XL
529 foreign_data.imported_source_files(sess)
530 };
531
b7449926 532 let source_file = {
9e0c209e 533 // Optimize for the case that most spans within a translated item
b7449926 534 // originate from the same source_file.
3dfed10e 535 let last_source_file = &imported_source_files[decoder.last_source_file_index];
9e0c209e 536
dfeec247
XL
537 if lo >= last_source_file.original_start_pos && lo <= last_source_file.original_end_pos
538 {
b7449926 539 last_source_file
9e0c209e 540 } else {
74b04a01
XL
541 let index = imported_source_files
542 .binary_search_by_key(&lo, |source_file| source_file.original_start_pos)
543 .unwrap_or_else(|index| index - 1);
e9174d1e 544
ba9703b0
XL
545 // Don't try to cache the index for foreign spans,
546 // as this would require a map from CrateNums to indices
547 if tag == TAG_VALID_SPAN_LOCAL {
3dfed10e 548 decoder.last_source_file_index = index;
ba9703b0 549 }
74b04a01 550 &imported_source_files[index]
e9174d1e 551 }
9e0c209e
SL
552 };
553
ff7c6d11 554 // Make sure our binary search above is correct.
ba9703b0
XL
555 debug_assert!(
556 lo >= source_file.original_start_pos && lo <= source_file.original_end_pos,
557 "Bad binary search: lo={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
558 lo,
559 source_file.original_start_pos,
560 source_file.original_end_pos
561 );
ff7c6d11 562
2c00a5a8 563 // Make sure we correctly filtered out invalid spans during encoding
ba9703b0
XL
564 debug_assert!(
565 hi >= source_file.original_start_pos && hi <= source_file.original_end_pos,
566 "Bad binary search: hi={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
567 hi,
568 source_file.original_start_pos,
569 source_file.original_end_pos
570 );
ff7c6d11 571
dfeec247
XL
572 let lo =
573 (lo + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
574 let hi =
575 (hi + source_file.translated_source_file.start_pos) - source_file.original_start_pos;
9e0c209e 576
c295e0f8 577 // Do not try to decode parent for foreign spans.
5099ac24 578 Span::new(lo, hi, ctxt, None)
e1599b0c
XL
579 }
580}
581
c295e0f8 582impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [thir::abstract_const::Node<'tcx>] {
5099ac24 583 fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
1b1a35ee
XL
584 ty::codec::RefDecodable::decode(d)
585 }
586}
587
3dfed10e 588impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for &'tcx [(ty::Predicate<'tcx>, Span)] {
5099ac24 589 fn decode(d: &mut DecodeContext<'a, 'tcx>) -> Self {
3dfed10e
XL
590 ty::codec::RefDecodable::decode(d)
591 }
592}
593
594impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
595 for Lazy<T>
596{
5099ac24 597 fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
3dfed10e 598 decoder.read_lazy_with_meta(())
2c00a5a8
XL
599 }
600}
601
3dfed10e
XL
602impl<'a, 'tcx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
603 for Lazy<[T]>
604{
5099ac24
FG
605 fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
606 let len = decoder.read_usize();
607 if len == 0 { Lazy::empty() } else { decoder.read_lazy_with_meta(len) }
3dfed10e
XL
608 }
609}
610
611impl<'a, 'tcx, I: Idx, T: Decodable<DecodeContext<'a, 'tcx>>> Decodable<DecodeContext<'a, 'tcx>>
612 for Lazy<Table<I, T>>
f035d41b 613where
3dfed10e 614 Option<T>: FixedSizeEncoding,
dfeec247 615{
5099ac24
FG
616 fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
617 let len = decoder.read_usize();
3dfed10e 618 decoder.read_lazy_with_meta(len)
ff7c6d11
XL
619 }
620}
621
dfeec247 622implement_ty_decoder!(DecodeContext<'a, 'tcx>);
ea8adc8c 623
a2a8927a 624impl<'tcx> MetadataBlob {
60c5eb7d 625 crate fn new(metadata_ref: MetadataRef) -> MetadataBlob {
c295e0f8 626 MetadataBlob(Lrc::new(metadata_ref))
60c5eb7d
XL
627 }
628
e74abb32 629 crate fn is_compatible(&self) -> bool {
c295e0f8 630 self.blob().starts_with(METADATA_HEADER)
85aaf69f 631 }
85aaf69f 632
e74abb32 633 crate fn get_rustc_version(&self) -> String {
dfeec247
XL
634 Lazy::<String>::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 4).unwrap())
635 .decode(self)
476ff2be
SL
636 }
637
e74abb32 638 crate fn get_root(&self) -> CrateRoot<'tcx> {
c295e0f8 639 let slice = &self.blob()[..];
9e0c209e 640 let offset = METADATA_HEADER.len();
dfeec247
XL
641 let pos = (((slice[offset + 0] as u32) << 24)
642 | ((slice[offset + 1] as u32) << 16)
643 | ((slice[offset + 2] as u32) << 8)
644 | ((slice[offset + 3] as u32) << 0)) as usize;
645 Lazy::<CrateRoot<'tcx>>::from_position(NonZeroUsize::new(pos).unwrap()).decode(self)
9e0c209e
SL
646 }
647
dfeec247 648 crate fn list_crate_metadata(&self, out: &mut dyn io::Write) -> io::Result<()> {
9e0c209e 649 let root = self.get_root();
136023e0
XL
650 writeln!(out, "Crate info:")?;
651 writeln!(out, "name {}{}", root.name, root.extra_filename)?;
652 writeln!(out, "hash {} stable_crate_id {:?}", root.hash, root.stable_crate_id)?;
653 writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
654 writeln!(out, "=External Dependencies=")?;
dfeec247 655 for (i, dep) in root.crate_deps.decode(self).enumerate() {
136023e0
XL
656 writeln!(
657 out,
658 "{} {}{} hash {} host_hash {:?} kind {:?}",
659 i + 1,
660 dep.name,
661 dep.extra_filename,
662 dep.hash,
663 dep.host_hash,
664 dep.kind
665 )?;
1a4d82fc 666 }
9e0c209e
SL
667 write!(out, "\n")?;
668 Ok(())
970d7e83 669 }
223e47cc
LB
670}
671
60c5eb7d 672impl CrateRoot<'_> {
e74abb32 673 crate fn is_proc_macro_crate(&self) -> bool {
60c5eb7d
XL
674 self.proc_macro_data.is_some()
675 }
676
677 crate fn name(&self) -> Symbol {
678 self.name
679 }
680
60c5eb7d
XL
681 crate fn hash(&self) -> Svh {
682 self.hash
683 }
684
6a06907d
XL
685 crate fn stable_crate_id(&self) -> StableCrateId {
686 self.stable_crate_id
687 }
688
60c5eb7d
XL
689 crate fn triple(&self) -> &TargetTriple {
690 &self.triple
691 }
692
a2a8927a 693 crate fn decode_crate_deps<'a>(
60c5eb7d
XL
694 &self,
695 metadata: &'a MetadataBlob,
696 ) -> impl ExactSizeIterator<Item = CrateDep> + Captures<'a> {
697 self.crate_deps.decode(metadata)
698 }
699}
700
74b04a01 701impl<'a, 'tcx> CrateMetadataRef<'a> {
5099ac24 702 fn raw_proc_macro(self, id: DefIndex) -> &'a ProcMacro {
e1599b0c
XL
703 // DefIndex's in root.proc_macro_data have a one-to-one correspondence
704 // with items in 'raw_proc_macros'.
1b1a35ee
XL
705 let pos = self
706 .root
707 .proc_macro_data
708 .as_ref()
709 .unwrap()
710 .macros
711 .decode(self)
712 .position(|i| i == id)
713 .unwrap();
e1599b0c
XL
714 &self.raw_proc_macros.unwrap()[pos]
715 }
716
5099ac24 717 fn opt_item_ident(self, item_index: DefIndex, sess: &Session) -> Option<Ident> {
a2a8927a
XL
718 let name = self.def_key(item_index).disambiguated_data.data.get_opt_name()?;
719 let span = match self.root.tables.ident_span.get(self, item_index) {
720 Some(lazy_span) => lazy_span.decode((self, sess)),
721 None => {
722 // FIXME: this weird case of a name with no span is specific to `extern crate`
723 // items, which are supposed to be treated like `use` items and only be encoded
724 // to metadata as `Export`s, return `None` because that's what all the callers
725 // expect in this case.
726 assert_eq!(self.def_kind(item_index), DefKind::ExternCrate);
727 return None;
728 }
729 };
730 Some(Ident::new(name, span))
223e47cc 731 }
223e47cc 732
5099ac24 733 fn item_ident(self, item_index: DefIndex, sess: &Session) -> Ident {
a2a8927a 734 self.opt_item_ident(item_index, sess).expect("no encoded ident for item")
5869c6ff
XL
735 }
736
5099ac24 737 fn maybe_kind(self, item_id: DefIndex) -> Option<EntryKind> {
5869c6ff
XL
738 self.root.tables.kind.get(self, item_id).map(|k| k.decode(self))
739 }
740
5099ac24 741 fn kind(self, item_id: DefIndex) -> EntryKind {
5869c6ff
XL
742 self.maybe_kind(item_id).unwrap_or_else(|| {
743 bug!(
744 "CrateMetadata::kind({:?}): id not found, in crate {:?} with number {}",
745 item_id,
746 self.root.name,
747 self.cnum,
748 )
749 })
750 }
751
5099ac24 752 fn def_kind(self, item_id: DefIndex) -> DefKind {
5869c6ff
XL
753 self.root.tables.def_kind.get(self, item_id).map(|k| k.decode(self)).unwrap_or_else(|| {
754 bug!(
755 "CrateMetadata::def_kind({:?}): id not found, in crate {:?} with number {}",
756 item_id,
757 self.root.name,
758 self.cnum,
759 )
760 })
476ff2be
SL
761 }
762
5099ac24 763 fn get_span(self, index: DefIndex, sess: &Session) -> Span {
1b1a35ee
XL
764 self.root
765 .tables
766 .span
767 .get(self, index)
768 .unwrap_or_else(|| panic!("Missing span for {:?}", index))
769 .decode((self, sess))
e1599b0c
XL
770 }
771
5099ac24 772 fn load_proc_macro(self, id: DefIndex, sess: &Session) -> SyntaxExtension {
136023e0 773 let (name, kind, helper_attrs) = match *self.raw_proc_macro(id) {
e1599b0c
XL
774 ProcMacro::CustomDerive { trait_name, attributes, client } => {
775 let helper_attrs =
776 attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
777 (
778 trait_name,
136023e0 779 SyntaxExtensionKind::Derive(Box::new(ProcMacroDerive { client })),
e1599b0c
XL
780 helper_attrs,
781 )
782 }
136023e0
XL
783 ProcMacro::Attr { name, client } => {
784 (name, SyntaxExtensionKind::Attr(Box::new(AttrProcMacro { client })), Vec::new())
785 }
786 ProcMacro::Bang { name, client } => {
787 (name, SyntaxExtensionKind::Bang(Box::new(BangProcMacro { client })), Vec::new())
788 }
e1599b0c 789 };
e1599b0c 790
136023e0 791 let attrs: Vec<_> = self.get_item_attrs(id, sess).collect();
e1599b0c 792 SyntaxExtension::new(
3dfed10e 793 sess,
e1599b0c 794 kind,
136023e0 795 self.get_span(id, sess),
e1599b0c 796 helper_attrs,
e74abb32 797 self.root.edition,
e1599b0c 798 Symbol::intern(name),
fc512014 799 &attrs,
e1599b0c 800 )
7453a54e
SL
801 }
802
5099ac24 803 fn get_trait_def(self, item_id: DefIndex, sess: &Session) -> ty::TraitDef {
e74abb32 804 match self.kind(item_id) {
9fa01778
XL
805 EntryKind::Trait(data) => {
806 let data = data.decode((self, sess));
dfeec247
XL
807 ty::TraitDef::new(
808 self.local_def_id(item_id),
809 data.unsafety,
810 data.paren_sugar,
811 data.has_auto_impl,
812 data.is_marker,
cdc7bbd5 813 data.skip_array_during_method_dispatch,
ba9703b0 814 data.specialization_kind,
3dfed10e 815 self.def_path_hash(item_id),
5099ac24 816 data.must_implement_one_of,
dfeec247
XL
817 )
818 }
819 EntryKind::TraitAlias => ty::TraitDef::new(
820 self.local_def_id(item_id),
821 hir::Unsafety::Normal,
822 false,
823 false,
824 false,
cdc7bbd5 825 false,
ba9703b0 826 ty::trait_def::TraitSpecializationKind::None,
3dfed10e 827 self.def_path_hash(item_id),
5099ac24 828 None,
dfeec247 829 ),
9fa01778
XL
830 _ => bug!("def-index does not refer to trait or trait alias"),
831 }
9e0c209e 832 }
9cc50fc6 833
532ac7d7 834 fn get_variant(
5099ac24 835 self,
74b04a01 836 kind: &EntryKind,
532ac7d7
XL
837 index: DefIndex,
838 parent_did: DefId,
ba9703b0 839 sess: &Session,
532ac7d7 840 ) -> ty::VariantDef {
e74abb32 841 let data = match kind {
dfeec247
XL
842 EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => {
843 data.decode(self)
844 }
c30ab7b3 845 _ => bug!(),
9cc50fc6 846 };
9cc50fc6 847
e74abb32
XL
848 let adt_kind = match kind {
849 EntryKind::Variant(_) => ty::AdtKind::Enum,
850 EntryKind::Struct(..) => ty::AdtKind::Struct,
851 EntryKind::Union(..) => ty::AdtKind::Union,
852 _ => bug!(),
853 };
854
dfeec247
XL
855 let variant_did =
856 if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
532ac7d7 857 let ctor_did = data.ctor.map(|index| self.local_def_id(index));
0bf4aa26 858
b7449926 859 ty::VariantDef::new(
5099ac24 860 self.item_ident(index, sess).name,
532ac7d7
XL
861 variant_did,
862 ctor_did,
b7449926 863 data.discr,
dfeec247 864 self.root
ba9703b0 865 .tables
dfeec247
XL
866 .children
867 .get(self, index)
29967ef6 868 .unwrap_or_else(Lazy::empty)
dfeec247
XL
869 .decode(self)
870 .map(|index| ty::FieldDef {
476ff2be 871 did: self.local_def_id(index),
5099ac24 872 name: self.item_ident(index, sess).name,
e74abb32 873 vis: self.get_visibility(index),
dfeec247
XL
874 })
875 .collect(),
0bf4aa26 876 data.ctor_kind,
532ac7d7
XL
877 adt_kind,
878 parent_did,
879 false,
3dfed10e 880 data.is_non_exhaustive,
b7449926 881 )
c30ab7b3
SL
882 }
883
5099ac24 884 fn get_adt_def(self, item_id: DefIndex, tcx: TyCtxt<'tcx>) -> &'tcx ty::AdtDef {
e74abb32 885 let kind = self.kind(item_id);
9e0c209e 886 let did = self.local_def_id(item_id);
94b46f34 887
e74abb32 888 let (adt_kind, repr) = match kind {
94b46f34
XL
889 EntryKind::Enum(repr) => (ty::AdtKind::Enum, repr),
890 EntryKind::Struct(_, repr) => (ty::AdtKind::Struct, repr),
891 EntryKind::Union(_, repr) => (ty::AdtKind::Union, repr),
8bb4bdeb
XL
892 _ => bug!("get_adt_def called on a non-ADT {:?}", did),
893 };
94b46f34 894
e74abb32 895 let variants = if let ty::AdtKind::Enum = adt_kind {
dfeec247 896 self.root
ba9703b0 897 .tables
dfeec247
XL
898 .children
899 .get(self, item_id)
29967ef6 900 .unwrap_or_else(Lazy::empty)
c30ab7b3 901 .decode(self)
3dfed10e 902 .map(|index| self.get_variant(&self.kind(index), index, did, tcx.sess))
c30ab7b3
SL
903 .collect()
904 } else {
3dfed10e 905 std::iter::once(self.get_variant(&kind, item_id, did, tcx.sess)).collect()
9e0c209e 906 };
9cc50fc6 907
e74abb32 908 tcx.alloc_adt_def(did, adt_kind, variants, repr)
9cc50fc6
SL
909 }
910
60c5eb7d 911 fn get_explicit_predicates(
5099ac24 912 self,
dc9dc135
XL
913 item_id: DefIndex,
914 tcx: TyCtxt<'tcx>,
915 ) -> ty::GenericPredicates<'tcx> {
ba9703b0 916 self.root.tables.explicit_predicates.get(self, item_id).unwrap().decode((self, tcx))
e74abb32 917 }
9cc50fc6 918
60c5eb7d 919 fn get_inferred_outlives(
5099ac24 920 self,
dc9dc135
XL
921 item_id: DefIndex,
922 tcx: TyCtxt<'tcx>,
60c5eb7d 923 ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
dfeec247 924 self.root
ba9703b0 925 .tables
dfeec247
XL
926 .inferred_outlives
927 .get(self, item_id)
29967ef6 928 .map(|predicates| tcx.arena.alloc_from_iter(predicates.decode((self, tcx))))
dfeec247 929 .unwrap_or_default()
8faf50e0
XL
930 }
931
60c5eb7d 932 fn get_super_predicates(
5099ac24 933 self,
dc9dc135
XL
934 item_id: DefIndex,
935 tcx: TyCtxt<'tcx>,
936 ) -> ty::GenericPredicates<'tcx> {
ba9703b0 937 self.root.tables.super_predicates.get(self, item_id).unwrap().decode((self, tcx))
9cc50fc6 938 }
9cc50fc6 939
29967ef6 940 fn get_explicit_item_bounds(
5099ac24 941 self,
29967ef6
XL
942 item_id: DefIndex,
943 tcx: TyCtxt<'tcx>,
944 ) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
945 self.root
946 .tables
947 .explicit_item_bounds
948 .get(self, item_id)
949 .map(|bounds| tcx.arena.alloc_from_iter(bounds.decode((self, tcx))))
950 .unwrap_or_default()
951 }
952
5099ac24 953 fn get_generics(self, item_id: DefIndex, sess: &Session) -> ty::Generics {
ba9703b0 954 self.root.tables.generics.get(self, item_id).unwrap().decode((self, sess))
223e47cc
LB
955 }
956
5099ac24 957 fn get_type(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
fc512014
XL
958 self.root
959 .tables
960 .ty
961 .get(self, id)
962 .unwrap_or_else(|| panic!("Not a type: {:?}", id))
963 .decode((self, tcx))
9e0c209e 964 }
223e47cc 965
5099ac24 966 fn get_stability(self, id: DefIndex) -> Option<attr::Stability> {
fc512014 967 self.root.tables.stability.get(self, id).map(|stab| stab.decode(self))
223e47cc 968 }
223e47cc 969
5099ac24 970 fn get_const_stability(self, id: DefIndex) -> Option<attr::ConstStability> {
ba9703b0 971 self.root.tables.const_stability.get(self, id).map(|stab| stab.decode(self))
60c5eb7d
XL
972 }
973
5099ac24 974 fn get_deprecation(self, id: DefIndex) -> Option<attr::Deprecation> {
fc512014 975 self.root.tables.deprecation.get(self, id).map(|depr| depr.decode(self))
9e0c209e 976 }
1a4d82fc 977
5099ac24 978 fn get_visibility(self, id: DefIndex) -> ty::Visibility {
fc512014 979 self.root.tables.visibility.get(self, id).unwrap().decode(self)
9e0c209e 980 }
1a4d82fc 981
5099ac24 982 fn get_impl_data(self, id: DefIndex) -> ImplData {
e74abb32 983 match self.kind(id) {
9e0c209e 984 EntryKind::Impl(data) => data.decode(self),
c30ab7b3 985 _ => bug!(),
1a4d82fc 986 }
223e47cc 987 }
223e47cc 988
5099ac24 989 fn get_parent_impl(self, id: DefIndex) -> Option<DefId> {
9e0c209e
SL
990 self.get_impl_data(id).parent_impl
991 }
1a4d82fc 992
5099ac24 993 fn get_impl_polarity(self, id: DefIndex) -> ty::ImplPolarity {
9e0c209e
SL
994 self.get_impl_data(id).polarity
995 }
223e47cc 996
5099ac24 997 fn get_impl_defaultness(self, id: DefIndex) -> hir::Defaultness {
7cac9316
XL
998 self.get_impl_data(id).defaultness
999 }
1000
5099ac24 1001 fn get_impl_constness(self, id: DefIndex) -> hir::Constness {
136023e0
XL
1002 self.get_impl_data(id).constness
1003 }
1004
5099ac24
FG
1005 fn get_trait_item_def_id(self, id: DefIndex) -> Option<DefId> {
1006 self.root.tables.trait_item_def_id.get(self, id).map(|d| d.decode(self))
1007 }
1008
1009 fn get_coerce_unsized_info(self, id: DefIndex) -> Option<ty::adjustment::CoerceUnsizedInfo> {
cc61c64b 1010 self.get_impl_data(id).coerce_unsized_info
9e0c209e 1011 }
1a4d82fc 1012
5099ac24 1013 fn get_impl_trait(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> Option<ty::TraitRef<'tcx>> {
ba9703b0 1014 self.root.tables.impl_trait_ref.get(self, id).map(|tr| tr.decode((self, tcx)))
9e0c209e 1015 }
223e47cc 1016
5099ac24 1017 fn get_expn_that_defined(self, id: DefIndex, sess: &Session) -> ExpnId {
29967ef6
XL
1018 self.root.tables.expn_that_defined.get(self, id).unwrap().decode((self, sess))
1019 }
1020
cdc7bbd5 1021 fn get_const_param_default(
5099ac24 1022 self,
cdc7bbd5
XL
1023 tcx: TyCtxt<'tcx>,
1024 id: DefIndex,
1025 ) -> rustc_middle::ty::Const<'tcx> {
1026 self.root.tables.const_defaults.get(self, id).unwrap().decode((self, tcx))
1027 }
1028
b7449926 1029 /// Iterates over all the stability attributes in the given crate.
5099ac24 1030 fn get_lib_features(self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Option<Symbol>)] {
dfeec247 1031 tcx.arena.alloc_from_iter(self.root.lib_features.decode(self))
9e0c209e 1032 }
223e47cc 1033
b7449926 1034 /// Iterates over the language items in the given crate.
5099ac24
FG
1035 fn get_lang_items(self) -> impl Iterator<Item = (DefId, usize)> + 'a {
1036 self.root
1037 .lang_items
1038 .decode(self)
1039 .map(move |(def_index, index)| (self.local_def_id(def_index), index))
b7449926
XL
1040 }
1041
e1599b0c 1042 /// Iterates over the diagnostic items in the given crate.
5099ac24
FG
1043 fn get_diagnostic_items(self) -> DiagnosticItems {
1044 let mut id_to_name = FxHashMap::default();
1045 let name_to_id = self
1046 .root
1047 .diagnostic_items
1048 .decode(self)
1049 .map(|(name, def_index)| {
1050 let id = self.local_def_id(def_index);
1051 id_to_name.insert(id, name);
1052 (name, id)
1053 })
1054 .collect();
1055 DiagnosticItems { id_to_name, name_to_id }
e1599b0c
XL
1056 }
1057
5099ac24
FG
1058 /// Iterates over all named children of the given module,
1059 /// including both proper items and reexports.
1060 /// Module here is understood in name resolution sense - it can be a `mod` item,
1061 /// or a crate root, or an enum, or a trait.
1062 fn for_each_module_child(
1063 self,
1064 id: DefIndex,
1065 mut callback: impl FnMut(ModChild),
1066 sess: &Session,
1067 ) {
1b1a35ee 1068 if let Some(data) = &self.root.proc_macro_data {
5099ac24
FG
1069 // If we are loading as a proc macro, we want to return
1070 // the view of this crate as a proc macro crate.
476ff2be 1071 if id == CRATE_DEF_INDEX {
5099ac24 1072 for def_index in data.macros.decode(self) {
e1599b0c 1073 let raw_macro = self.raw_proc_macro(def_index);
48663c56 1074 let res = Res::Def(
e1599b0c
XL
1075 DefKind::Macro(macro_kind(raw_macro)),
1076 self.local_def_id(def_index),
8bb4bdeb 1077 );
f035d41b 1078 let ident = self.item_ident(def_index, sess);
5099ac24
FG
1079 callback(ModChild {
1080 ident,
1081 res,
1082 vis: ty::Visibility::Public,
1083 span: ident.span,
1084 });
476ff2be
SL
1085 }
1086 }
dfeec247 1087 return;
476ff2be
SL
1088 }
1089
9e0c209e 1090 // Iterate over all children.
a2a8927a 1091 if let Some(children) = self.root.tables.children.get(self, id) {
5869c6ff 1092 for child_index in children.decode((self, sess)) {
a2a8927a
XL
1093 if let Some(ident) = self.opt_item_ident(child_index, sess) {
1094 let kind = self.def_kind(child_index);
1095 if matches!(kind, DefKind::Macro(..)) {
1096 // FIXME: Macros are currently encoded twice, once as items and once as
1097 // reexports. We ignore the items here and only use the reexports.
9e0c209e
SL
1098 continue;
1099 }
48663c56
XL
1100 let def_id = self.local_def_id(child_index);
1101 let res = Res::Def(kind, def_id);
a2a8927a
XL
1102 let vis = self.get_visibility(child_index);
1103 let span = self.get_span(child_index, sess);
94222f64 1104
5099ac24 1105 callback(ModChild { ident, res, vis, span });
94222f64 1106
2c00a5a8
XL
1107 // For non-re-export structs and variants add their constructors to children.
1108 // Re-export lists automatically contain constructors when necessary.
48663c56
XL
1109 match kind {
1110 DefKind::Struct => {
a2a8927a
XL
1111 if let Some((ctor_def_id, ctor_kind)) =
1112 self.get_ctor_def_id_and_kind(child_index)
1113 {
dfeec247
XL
1114 let ctor_res =
1115 Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id);
532ac7d7 1116 let vis = self.get_visibility(ctor_def_id.index);
5099ac24 1117 callback(ModChild { ident, res: ctor_res, vis, span });
c30ab7b3
SL
1118 }
1119 }
48663c56 1120 DefKind::Variant => {
c30ab7b3
SL
1121 // Braced variants, unlike structs, generate unusable names in
1122 // value namespace, they are reserved for possible future use.
532ac7d7
XL
1123 // It's ok to use the variant's id as a ctor id since an
1124 // error will be reported on any use of such resolution anyway.
a2a8927a
XL
1125 let (ctor_def_id, ctor_kind) = self
1126 .get_ctor_def_id_and_kind(child_index)
1127 .unwrap_or((def_id, CtorKind::Fictive));
dfeec247
XL
1128 let ctor_res =
1129 Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id);
48663c56 1130 let mut vis = self.get_visibility(ctor_def_id.index);
3c0e092e 1131 if ctor_def_id == def_id && vis.is_public() {
48663c56
XL
1132 // For non-exhaustive variants lower the constructor visibility to
1133 // within the crate. We only need this for fictive constructors,
1134 // for other constructors correct visibilities
1135 // were already encoded in metadata.
5869c6ff
XL
1136 let mut attrs = self.get_item_attrs(def_id.index, sess);
1137 if attrs.any(|item| item.has_name(sym::non_exhaustive)) {
48663c56
XL
1138 let crate_def_id = self.local_def_id(CRATE_DEF_INDEX);
1139 vis = ty::Visibility::Restricted(crate_def_id);
1140 }
1141 }
5099ac24 1142 callback(ModChild { ident, res: ctor_res, vis, span });
c30ab7b3
SL
1143 }
1144 _ => {}
1145 }
d9579d0f
AL
1146 }
1147 }
9e0c209e 1148 }
7453a54e 1149
5099ac24
FG
1150 match self.kind(id) {
1151 EntryKind::Mod(exports) => {
1152 for exp in exports.decode((self, sess)) {
1153 callback(exp);
1154 }
9e0c209e 1155 }
5099ac24
FG
1156 EntryKind::Enum(..) | EntryKind::Trait(..) => {}
1157 _ => bug!("`for_each_module_child` is called on a non-module: {:?}", self.def_kind(id)),
9e0c209e
SL
1158 }
1159 }
1a4d82fc 1160
5099ac24 1161 fn is_ctfe_mir_available(self, id: DefIndex) -> bool {
5869c6ff
XL
1162 self.root.tables.mir_for_ctfe.get(self, id).is_some()
1163 }
1164
5099ac24 1165 fn is_item_mir_available(self, id: DefIndex) -> bool {
fc512014 1166 self.root.tables.mir.get(self, id).is_some()
9e0c209e 1167 }
1a4d82fc 1168
5099ac24 1169 fn module_expansion(self, id: DefIndex, sess: &Session) -> ExpnId {
3c0e092e
XL
1170 match self.kind(id) {
1171 EntryKind::Mod(_) | EntryKind::Enum(_) | EntryKind::Trait(_) => {
1172 self.get_expn_that_defined(id, sess)
1173 }
1174 _ => panic!("Expected module, found {:?}", self.local_def_id(id)),
3dfed10e
XL
1175 }
1176 }
1177
5099ac24 1178 fn get_optimized_mir(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
f9f354fc 1179 self.root
ba9703b0 1180 .tables
dfeec247
XL
1181 .mir
1182 .get(self, id)
e1599b0c 1183 .unwrap_or_else(|| {
e74abb32 1184 bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id))
e1599b0c 1185 })
f9f354fc 1186 .decode((self, tcx))
e1599b0c
XL
1187 }
1188
5099ac24 1189 fn get_mir_for_ctfe(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
5869c6ff
XL
1190 self.root
1191 .tables
1192 .mir_for_ctfe
1193 .get(self, id)
1194 .unwrap_or_else(|| {
1195 bug!("get_mir_for_ctfe: missing MIR for `{:?}`", self.local_def_id(id))
1196 })
1197 .decode((self, tcx))
1198 }
1199
c295e0f8 1200 fn get_thir_abstract_const(
5099ac24 1201 self,
1b1a35ee
XL
1202 tcx: TyCtxt<'tcx>,
1203 id: DefIndex,
c295e0f8 1204 ) -> Result<Option<&'tcx [thir::abstract_const::Node<'tcx>]>, ErrorReported> {
1b1a35ee
XL
1205 self.root
1206 .tables
c295e0f8 1207 .thir_abstract_consts
1b1a35ee 1208 .get(self, id)
1b1a35ee
XL
1209 .map_or(Ok(None), |v| Ok(Some(v.decode((self, tcx)))))
1210 }
1211
5099ac24 1212 fn get_unused_generic_params(self, id: DefIndex) -> FiniteBitSet<u32> {
3dfed10e
XL
1213 self.root
1214 .tables
1215 .unused_generic_params
1216 .get(self, id)
3dfed10e
XL
1217 .map(|params| params.decode(self))
1218 .unwrap_or_default()
1219 }
1220
5099ac24 1221 fn get_promoted_mir(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> IndexVec<Promoted, Body<'tcx>> {
f9f354fc 1222 self.root
ba9703b0 1223 .tables
dfeec247
XL
1224 .promoted_mir
1225 .get(self, id)
e1599b0c
XL
1226 .unwrap_or_else(|| {
1227 bug!("get_promoted_mir: missing MIR for `{:?}`", self.local_def_id(id))
1228 })
f9f354fc 1229 .decode((self, tcx))
223e47cc 1230 }
223e47cc 1231
5099ac24 1232 fn mir_const_qualif(self, id: DefIndex) -> mir::ConstQualifs {
e74abb32 1233 match self.kind(id) {
f035d41b
XL
1234 EntryKind::AnonConst(qualif, _)
1235 | EntryKind::Const(qualif, _)
ba9703b0 1236 | EntryKind::AssocConst(
f9f354fc
XL
1237 AssocContainer::ImplDefault
1238 | AssocContainer::ImplFinal
1239 | AssocContainer::TraitWithDefault,
ba9703b0
XL
1240 qualif,
1241 _,
1242 ) => qualif,
f9f354fc 1243 _ => bug!("mir_const_qualif: unexpected kind"),
8bb4bdeb
XL
1244 }
1245 }
1246
5099ac24 1247 fn get_fn_has_self_parameter(self, id: DefIndex) -> bool {
a2a8927a
XL
1248 match self.kind(id) {
1249 EntryKind::AssocFn(data) => data.decode(self).has_self,
1250 _ => false,
1251 }
1252 }
1253
5099ac24
FG
1254 fn get_associated_item_def_ids(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [DefId] {
1255 if let Some(children) = self.root.tables.children.get(self, id) {
1256 tcx.arena.alloc_from_iter(
1257 children.decode((self, tcx.sess)).map(|child_index| self.local_def_id(child_index)),
1258 )
1259 } else {
1260 &[]
1261 }
1262 }
1263
1264 fn get_associated_item(self, id: DefIndex, sess: &Session) -> ty::AssocItem {
8bb4bdeb
XL
1265 let def_key = self.def_key(id);
1266 let parent = self.local_def_id(def_key.parent.unwrap());
ba9703b0 1267 let ident = self.item_ident(id, sess);
223e47cc 1268
e74abb32 1269 let (kind, container, has_self) = match self.kind(id) {
dfeec247 1270 EntryKind::AssocConst(container, _, _) => (ty::AssocKind::Const, container, false),
ba9703b0 1271 EntryKind::AssocFn(data) => {
9e0c209e 1272 let data = data.decode(self);
ba9703b0 1273 (ty::AssocKind::Fn, data.container, data.has_self)
9e0c209e 1274 }
dfeec247 1275 EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false),
dfeec247 1276 _ => bug!("cannot get associated-item of `{:?}`", def_key),
8bb4bdeb
XL
1277 };
1278
dc9dc135 1279 ty::AssocItem {
5099ac24 1280 name: ident.name,
3b2f2976 1281 kind,
e74abb32 1282 vis: self.get_visibility(id),
8bb4bdeb
XL
1283 defaultness: container.defaultness(),
1284 def_id: self.local_def_id(id),
5099ac24 1285 trait_item_def_id: self.get_trait_item_def_id(id),
8bb4bdeb 1286 container: container.with_def_id(parent),
ba9703b0 1287 fn_has_self_parameter: has_self,
8bb4bdeb 1288 }
9e0c209e 1289 }
223e47cc 1290
5099ac24 1291 fn get_item_variances(self, id: DefIndex) -> impl Iterator<Item = ty::Variance> + 'a {
fc512014 1292 self.root.tables.variances.get(self, id).unwrap_or_else(Lazy::empty).decode(self)
223e47cc 1293 }
223e47cc 1294
5099ac24 1295 fn get_ctor_def_id_and_kind(self, node_id: DefIndex) -> Option<(DefId, CtorKind)> {
e74abb32 1296 match self.kind(node_id) {
a2a8927a
XL
1297 EntryKind::Struct(data, _) | EntryKind::Variant(data) => {
1298 let vdata = data.decode(self);
1299 vdata.ctor.map(|index| (self.local_def_id(index), vdata.ctor_kind))
9e0c209e 1300 }
c30ab7b3 1301 _ => None,
9e0c209e 1302 }
223e47cc
LB
1303 }
1304
fc512014 1305 fn get_item_attrs(
5099ac24 1306 self,
a2a8927a 1307 id: DefIndex,
fc512014
XL
1308 sess: &'a Session,
1309 ) -> impl Iterator<Item = ast::Attribute> + 'a {
ba9703b0
XL
1310 self.root
1311 .tables
1312 .attributes
a2a8927a
XL
1313 .get(self, id)
1314 .unwrap_or_else(|| {
1315 // Structure and variant constructors don't have any attributes encoded for them,
1316 // but we assume that someone passing a constructor ID actually wants to look at
1317 // the attributes on the corresponding struct or variant.
1318 let def_key = self.def_key(id);
1319 assert_eq!(def_key.disambiguated_data.data, DefPathData::Ctor);
1320 let parent_id = def_key.parent.expect("no parent for a constructor");
1321 self.root
1322 .tables
1323 .attributes
1324 .get(self, parent_id)
1325 .expect("no encoded attributes for a structure or variant")
1326 })
ba9703b0 1327 .decode((self, sess))
9e0c209e 1328 }
223e47cc 1329
5099ac24
FG
1330 fn get_struct_field_names(
1331 self,
1332 id: DefIndex,
1333 sess: &'a Session,
1334 ) -> impl Iterator<Item = Spanned<Symbol>> + 'a {
dfeec247 1335 self.root
ba9703b0 1336 .tables
dfeec247
XL
1337 .children
1338 .get(self, id)
29967ef6 1339 .unwrap_or_else(Lazy::empty)
c30ab7b3 1340 .decode(self)
5099ac24 1341 .map(move |index| respan(self.get_span(index, sess), self.item_ident(index, sess).name))
9e0c209e 1342 }
223e47cc 1343
5099ac24 1344 fn get_struct_field_visibilities(self, id: DefIndex) -> impl Iterator<Item = Visibility> + 'a {
17df50a5
XL
1345 self.root
1346 .tables
1347 .children
1348 .get(self, id)
1349 .unwrap_or_else(Lazy::empty)
1350 .decode(self)
5099ac24 1351 .map(move |field_index| self.get_visibility(field_index))
17df50a5
XL
1352 }
1353
60c5eb7d 1354 fn get_inherent_implementations_for_type(
5099ac24 1355 self,
dc9dc135
XL
1356 tcx: TyCtxt<'tcx>,
1357 id: DefIndex,
1358 ) -> &'tcx [DefId] {
e74abb32 1359 tcx.arena.alloc_from_iter(
dfeec247 1360 self.root
ba9703b0 1361 .tables
dfeec247
XL
1362 .inherent_impls
1363 .get(self, id)
29967ef6 1364 .unwrap_or_else(Lazy::empty)
e74abb32 1365 .decode(self)
dfeec247 1366 .map(|index| self.local_def_id(index)),
e74abb32 1367 )
9e0c209e 1368 }
223e47cc 1369
5099ac24
FG
1370 /// Decodes all inherent impls in the crate (for rustdoc).
1371 fn get_inherent_impls(self) -> impl Iterator<Item = (DefId, DefId)> + 'a {
1372 (0..self.root.tables.inherent_impls.size()).flat_map(move |i| {
1373 let ty_index = DefIndex::from_usize(i);
1374 let ty_def_id = self.local_def_id(ty_index);
1375 self.root
1376 .tables
1377 .inherent_impls
1378 .get(self, ty_index)
1379 .unwrap_or_else(Lazy::empty)
1380 .decode(self)
1381 .map(move |impl_index| (ty_def_id, self.local_def_id(impl_index)))
1382 })
a2a8927a
XL
1383 }
1384
5099ac24
FG
1385 /// Decodes all traits in the crate (for rustdoc and rustc diagnostics).
1386 fn get_traits(self) -> impl Iterator<Item = DefId> + 'a {
1387 self.root.traits.decode(self).map(move |index| self.local_def_id(index))
1388 }
1389
1390 /// Decodes all trait impls in the crate (for rustdoc).
1391 fn get_trait_impls(self) -> impl Iterator<Item = (DefId, DefId, Option<SimplifiedType>)> + 'a {
1392 self.cdata.trait_impls.iter().flat_map(move |((trait_cnum_raw, trait_index), impls)| {
1393 let trait_def_id = DefId {
1394 krate: self.cnum_map[CrateNum::from_u32(*trait_cnum_raw)],
1395 index: *trait_index,
1396 };
1397 impls.decode(self).map(move |(impl_index, simplified_self_ty)| {
1398 (trait_def_id, self.local_def_id(impl_index), simplified_self_ty)
1399 })
a2a8927a
XL
1400 })
1401 }
1402
1403 fn get_implementations_of_trait(
5099ac24 1404 self,
dc9dc135 1405 tcx: TyCtxt<'tcx>,
a2a8927a
XL
1406 trait_def_id: DefId,
1407 ) -> &'tcx [(DefId, Option<SimplifiedType>)] {
5099ac24 1408 if self.trait_impls.is_empty() {
dfeec247 1409 return &[];
b7449926
XL
1410 }
1411
a2a8927a
XL
1412 // Do a reverse lookup beforehand to avoid touching the crate_num
1413 // hash map in the loop below.
1414 let key = match self.reverse_translate_def_id(trait_def_id) {
1415 Some(def_id) => (def_id.krate.as_u32(), def_id.index),
1416 None => return &[],
1417 };
223e47cc 1418
a2a8927a
XL
1419 if let Some(impls) = self.trait_impls.get(&key) {
1420 tcx.arena.alloc_from_iter(
3dfed10e
XL
1421 impls
1422 .decode(self)
a2a8927a
XL
1423 .map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty)),
1424 )
1425 } else {
1426 &[]
9e0c209e
SL
1427 }
1428 }
223e47cc 1429
5099ac24 1430 fn get_trait_of_item(self, id: DefIndex) -> Option<DefId> {
83c7162d
XL
1431 let def_key = self.def_key(id);
1432 match def_key.disambiguated_data.data {
1433 DefPathData::TypeNs(..) | DefPathData::ValueNs(..) => (),
1434 // Not an associated item
1435 _ => return None,
1436 }
dfeec247
XL
1437 def_key.parent.and_then(|parent_index| match self.kind(parent_index) {
1438 EntryKind::Trait(_) | EntryKind::TraitAlias => Some(self.local_def_id(parent_index)),
1439 _ => None,
9e0c209e
SL
1440 })
1441 }
223e47cc 1442
5099ac24
FG
1443 fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> + 'a {
1444 self.root.native_libraries.decode((self, sess))
223e47cc
LB
1445 }
1446
5099ac24 1447 fn get_proc_macro_quoted_span(self, index: usize, sess: &Session) -> Span {
17df50a5
XL
1448 self.root
1449 .tables
1450 .proc_macro_quoted_spans
1451 .get(self, index)
1452 .unwrap_or_else(|| panic!("Missing proc macro quoted span: {:?}", index))
1453 .decode((self, sess))
1454 }
1455
5099ac24
FG
1456 fn get_foreign_modules(self, sess: &'a Session) -> impl Iterator<Item = ForeignModule> + '_ {
1457 self.root.foreign_modules.decode((self, sess))
0531ce1d
XL
1458 }
1459
60c5eb7d 1460 fn get_dylib_dependency_formats(
5099ac24 1461 self,
dc9dc135
XL
1462 tcx: TyCtxt<'tcx>,
1463 ) -> &'tcx [(CrateNum, LinkagePreference)] {
dfeec247
XL
1464 tcx.arena.alloc_from_iter(
1465 self.root.dylib_dependency_formats.decode(self).enumerate().flat_map(|(i, link)| {
c30ab7b3 1466 let cnum = CrateNum::new(i + 1);
94b46f34 1467 link.map(|link| (self.cnum_map[cnum], link))
dfeec247
XL
1468 }),
1469 )
223e47cc 1470 }
223e47cc 1471
5099ac24
FG
1472 fn get_missing_lang_items(self, tcx: TyCtxt<'tcx>) -> &'tcx [lang_items::LangItem] {
1473 tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self))
d9579d0f
AL
1474 }
1475
5099ac24 1476 fn get_fn_param_names(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> &'tcx [Ident] {
e74abb32 1477 let param_names = match self.kind(id) {
dfeec247 1478 EntryKind::Fn(data) | EntryKind::ForeignFn(data) => data.decode(self).param_names,
ba9703b0 1479 EntryKind::AssocFn(data) => data.decode(self).fn_data.param_names,
e1599b0c 1480 _ => Lazy::empty(),
9e0c209e 1481 };
f035d41b 1482 tcx.arena.alloc_from_iter(param_names.decode((self, tcx)))
9e0c209e 1483 }
9cc50fc6 1484
60c5eb7d 1485 fn exported_symbols(
5099ac24 1486 self,
dc9dc135 1487 tcx: TyCtxt<'tcx>,
ba9703b0 1488 ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportLevel)] {
5099ac24 1489 tcx.arena.alloc_from_iter(self.root.exported_symbols.decode((self, tcx)))
83c7162d
XL
1490 }
1491
5099ac24 1492 fn get_rendered_const(self, id: DefIndex) -> String {
e74abb32 1493 match self.kind(id) {
f035d41b
XL
1494 EntryKind::AnonConst(_, data)
1495 | EntryKind::Const(_, data)
1496 | EntryKind::AssocConst(_, _, data) => data.decode(self).0,
83c7162d
XL
1497 _ => bug!(),
1498 }
476ff2be
SL
1499 }
1500
5099ac24 1501 fn get_macro(self, id: DefIndex, sess: &Session) -> MacroDef {
e74abb32 1502 match self.kind(id) {
ba9703b0 1503 EntryKind::MacroDef(macro_def) => macro_def.decode((self, sess)),
476ff2be
SL
1504 _ => bug!(),
1505 }
9e0c209e 1506 }
9cc50fc6 1507
60c5eb7d
XL
1508 // This replicates some of the logic of the crate-local `is_const_fn_raw` query, because we
1509 // don't serialize constness for tuple variant and tuple struct constructors.
5099ac24 1510 fn is_const_fn_raw(self, id: DefIndex) -> bool {
e74abb32 1511 let constness = match self.kind(id) {
ba9703b0 1512 EntryKind::AssocFn(data) => data.decode(self).fn_data.constness,
32a655c1 1513 EntryKind::Fn(data) => data.decode(self).constness,
60c5eb7d 1514 EntryKind::ForeignFn(data) => data.decode(self).constness,
dc9dc135 1515 EntryKind::Variant(..) | EntryKind::Struct(..) => hir::Constness::Const,
32a655c1
SL
1516 _ => hir::Constness::NotConst,
1517 };
1518 constness == hir::Constness::Const
9e0c209e 1519 }
9cc50fc6 1520
5099ac24 1521 fn asyncness(self, id: DefIndex) -> hir::IsAsync {
dfeec247 1522 match self.kind(id) {
e1599b0c 1523 EntryKind::Fn(data) => data.decode(self).asyncness,
ba9703b0 1524 EntryKind::AssocFn(data) => data.decode(self).fn_data.asyncness,
e1599b0c 1525 EntryKind::ForeignFn(data) => data.decode(self).asyncness,
e74abb32 1526 _ => bug!("asyncness: expected function kind"),
e1599b0c
XL
1527 }
1528 }
1529
5099ac24 1530 fn is_foreign_item(self, id: DefIndex) -> bool {
e74abb32 1531 match self.kind(id) {
dfeec247
XL
1532 EntryKind::ForeignImmStatic | EntryKind::ForeignMutStatic | EntryKind::ForeignFn(_) => {
1533 true
1534 }
c30ab7b3 1535 _ => false,
62682a34 1536 }
d9579d0f 1537 }
1a4d82fc 1538
5099ac24 1539 fn static_mutability(self, id: DefIndex) -> Option<hir::Mutability> {
e74abb32 1540 match self.kind(id) {
dfeec247
XL
1541 EntryKind::ImmStatic | EntryKind::ForeignImmStatic => Some(hir::Mutability::Not),
1542 EntryKind::MutStatic | EntryKind::ForeignMutStatic => Some(hir::Mutability::Mut),
48663c56
XL
1543 _ => None,
1544 }
1545 }
1546
5099ac24 1547 fn generator_kind(self, id: DefIndex) -> Option<hir::GeneratorKind> {
74b04a01
XL
1548 match self.kind(id) {
1549 EntryKind::Generator(data) => Some(data),
1550 _ => None,
1551 }
1552 }
1553
5099ac24 1554 fn fn_sig(self, id: DefIndex, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
ba9703b0 1555 self.root.tables.fn_sig.get(self, id).unwrap().decode((self, tcx))
1a4d82fc 1556 }
1a4d82fc 1557
cc61c64b 1558 #[inline]
5099ac24 1559 fn def_key(self, index: DefIndex) -> DefKey {
fc512014
XL
1560 *self
1561 .def_key_cache
1562 .lock()
1563 .entry(index)
1564 .or_insert_with(|| self.root.tables.def_keys.get(self, index).unwrap().decode(self))
1565 }
1566
32a655c1 1567 // Returns the path leading to the thing with this `id`.
5099ac24 1568 fn def_path(self, id: DefIndex) -> DefPath {
b7449926 1569 debug!("def_path(cnum={:?}, id={:?})", self.cnum, id);
e1599b0c 1570 DefPath::make(self.cnum, id, |parent| self.def_key(parent))
92a42be0 1571 }
92a42be0 1572
3dfed10e 1573 fn def_path_hash_unlocked(
5099ac24 1574 self,
3dfed10e
XL
1575 index: DefIndex,
1576 def_path_hashes: &mut FxHashMap<DefIndex, DefPathHash>,
1577 ) -> DefPathHash {
1578 *def_path_hashes.entry(index).or_insert_with(|| {
1579 self.root.tables.def_path_hashes.get(self, index).unwrap().decode(self)
1580 })
1581 }
1582
1583 #[inline]
5099ac24 1584 fn def_path_hash(self, index: DefIndex) -> DefPathHash {
3dfed10e
XL
1585 let mut def_path_hashes = self.def_path_hash_cache.lock();
1586 self.def_path_hash_unlocked(index, &mut def_path_hashes)
1587 }
1588
c295e0f8 1589 #[inline]
5099ac24 1590 fn def_path_hash_to_def_index(self, hash: DefPathHash) -> DefIndex {
c295e0f8
XL
1591 self.def_path_hash_map.def_path_hash_to_def_index(&hash)
1592 }
1593
5099ac24 1594 fn expn_hash_to_expn_id(self, sess: &Session, index_guess: u32, hash: ExpnHash) -> ExpnId {
136023e0
XL
1595 debug_assert_eq!(ExpnId::from_hash(hash), None);
1596 let index_guess = ExpnIndex::from_u32(index_guess);
1597 let old_hash = self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode(self));
1598
1599 let index = if old_hash == Some(hash) {
1600 // Fast path: the expn and its index is unchanged from the
1601 // previous compilation session. There is no need to decode anything
1602 // else.
1603 index_guess
1604 } else {
1605 // Slow path: We need to find out the new `DefIndex` of the provided
1606 // `DefPathHash`, if its still exists. This requires decoding every `DefPathHash`
1607 // stored in this crate.
1608 let map = self.cdata.expn_hash_map.get_or_init(|| {
1609 let end_id = self.root.expn_hashes.size() as u32;
1610 let mut map =
1611 UnhashMap::with_capacity_and_hasher(end_id as usize, Default::default());
1612 for i in 0..end_id {
1613 let i = ExpnIndex::from_u32(i);
1614 if let Some(hash) = self.root.expn_hashes.get(self, i) {
1615 map.insert(hash.decode(self), i);
136023e0
XL
1616 }
1617 }
1618 map
1619 });
1620 map[&hash]
1621 };
1622
c295e0f8 1623 let data = self.root.expn_data.get(self, index).unwrap().decode((self, sess));
136023e0
XL
1624 rustc_span::hygiene::register_expn_id(self.cnum, index, data, hash)
1625 }
1626
b7449926 1627 /// Imports the source_map from an external crate into the source_map of the crate
9e0c209e
SL
1628 /// currently being compiled (the "local crate").
1629 ///
1630 /// The import algorithm works analogous to how AST items are inlined from an
1631 /// external crate's metadata:
b7449926
XL
1632 /// For every SourceFile in the external source_map an 'inline' copy is created in the
1633 /// local source_map. The correspondence relation between external and local
1634 /// SourceFiles is recorded in the `ImportedSourceFile` objects returned from this
9e0c209e
SL
1635 /// function. When an item from an external crate is later inlined into this
1636 /// crate, this correspondence information is used to translate the span
1637 /// information of the inlined item so that it refers the correct positions in
b7449926 1638 /// the local source_map (see `<decoder::DecodeContext as SpecializedDecoder<Span>>`).
9e0c209e 1639 ///
b7449926
XL
1640 /// The import algorithm in the function below will reuse SourceFiles already
1641 /// existing in the local source_map. For example, even if the SourceFile of some
9e0c209e 1642 /// source file of libstd gets imported many times, there will only ever be
b7449926 1643 /// one SourceFile object for the corresponding file in the local source_map.
9e0c209e 1644 ///
b7449926 1645 /// Note that imported SourceFiles do not actually contain the source code of the
9e0c209e
SL
1646 /// file they represent, just information about length, line breaks, and
1647 /// multibyte characters. This information is enough to generate valid debuginfo
1648 /// for items inlined from other crates.
b7449926
XL
1649 ///
1650 /// Proc macro crates don't currently export spans, so this function does not have
1651 /// to work for them.
5099ac24 1652 fn imported_source_files(self, sess: &Session) -> &'a [ImportedSourceFile] {
ba9703b0
XL
1653 // Translate the virtual `/rustc/$hash` prefix back to a real directory
1654 // that should hold actual sources, where possible.
3dfed10e
XL
1655 //
1656 // NOTE: if you update this, you might need to also update bootstrap's code for generating
1657 // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
ba9703b0
XL
1658 let virtual_rust_source_base_dir = option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR")
1659 .map(Path::new)
1660 .filter(|_| {
1661 // Only spend time on further checks if we have what to translate *to*.
cdc7bbd5 1662 sess.opts.real_rust_source_base_dir.is_some()
ba9703b0
XL
1663 })
1664 .filter(|virtual_dir| {
1665 // Don't translate away `/rustc/$hash` if we're still remapping to it,
1666 // since that means we're still building `std`/`rustc` that need it,
1667 // and we don't want the real path to leak into codegen/debuginfo.
1668 !sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir)
1669 });
1670 let try_to_translate_virtual_to_real = |name: &mut rustc_span::FileName| {
1671 debug!(
1672 "try_to_translate_virtual_to_real(name={:?}): \
1673 virtual_rust_source_base_dir={:?}, real_rust_source_base_dir={:?}",
cdc7bbd5 1674 name, virtual_rust_source_base_dir, sess.opts.real_rust_source_base_dir,
ba9703b0
XL
1675 );
1676
1677 if let Some(virtual_dir) = virtual_rust_source_base_dir {
cdc7bbd5 1678 if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
ba9703b0 1679 if let rustc_span::FileName::Real(old_name) = name {
17df50a5
XL
1680 if let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
1681 old_name
1682 {
1683 if let Ok(rest) = virtual_name.strip_prefix(virtual_dir) {
1684 let virtual_name = virtual_name.clone();
3dfed10e
XL
1685
1686 // The std library crates are in
1687 // `$sysroot/lib/rustlib/src/rust/library`, whereas other crates
1688 // may be in `$sysroot/lib/rustlib/src/rust/` directly. So we
1689 // detect crates from the std libs and handle them specially.
1690 const STD_LIBS: &[&str] = &[
1691 "core",
1692 "alloc",
1693 "std",
1694 "test",
1695 "term",
1696 "unwind",
1697 "proc_macro",
1698 "panic_abort",
1699 "panic_unwind",
1700 "profiler_builtins",
1701 "rtstartup",
1702 "rustc-std-workspace-core",
1703 "rustc-std-workspace-alloc",
1704 "rustc-std-workspace-std",
1705 "backtrace",
1706 ];
1707 let is_std_lib = STD_LIBS.iter().any(|l| rest.starts_with(l));
1708
1709 let new_path = if is_std_lib {
1710 real_dir.join("library").join(rest)
1711 } else {
1712 real_dir.join(rest)
1713 };
1714
ba9703b0
XL
1715 debug!(
1716 "try_to_translate_virtual_to_real: `{}` -> `{}`",
1717 virtual_name.display(),
1718 new_path.display(),
1719 );
17df50a5
XL
1720 let new_name = rustc_span::RealFileName::Remapped {
1721 local_path: Some(new_path),
ba9703b0
XL
1722 virtual_name,
1723 };
1724 *old_name = new_name;
1725 }
1726 }
1727 }
1728 }
1729 }
1730 };
1731
f9f354fc 1732 self.cdata.source_map_import_info.get_or_init(|| {
e74abb32
XL
1733 let external_source_map = self.root.source_map.decode(self);
1734
dfeec247
XL
1735 external_source_map
1736 .map(|source_file_to_import| {
1737 // We can't reuse an existing SourceFile, so allocate a new one
1738 // containing the information we need.
1739 let rustc_span::SourceFile {
ba9703b0 1740 mut name,
dfeec247
XL
1741 src_hash,
1742 start_pos,
1743 end_pos,
1744 mut lines,
1745 mut multibyte_chars,
1746 mut non_narrow_chars,
1747 mut normalized_pos,
1748 name_hash,
1749 ..
1750 } = source_file_to_import;
1751
17df50a5
XL
1752 // If this file is under $sysroot/lib/rustlib/src/ but has not been remapped
1753 // during rust bootstrapping by `remap-debuginfo = true`, and the user
1754 // wish to simulate that behaviour by -Z simulate-remapped-rust-src-base,
1755 // then we change `name` to a similar state as if the rust was bootstrapped
1756 // with `remap-debuginfo = true`.
1757 // This is useful for testing so that tests about the effects of
1758 // `try_to_translate_virtual_to_real` don't have to worry about how the
1759 // compiler is bootstrapped.
1760 if let Some(virtual_dir) =
1761 &sess.opts.debugging_opts.simulate_remapped_rust_src_base
1762 {
1763 if let Some(real_dir) = &sess.opts.real_rust_source_base_dir {
1764 if let rustc_span::FileName::Real(ref mut old_name) = name {
1765 if let rustc_span::RealFileName::LocalPath(local) = old_name {
1766 if let Ok(rest) = local.strip_prefix(real_dir) {
1767 *old_name = rustc_span::RealFileName::Remapped {
1768 local_path: None,
1769 virtual_name: virtual_dir.join(rest),
1770 };
1771 }
1772 }
1773 }
1774 }
1775 }
1776
ba9703b0
XL
1777 // If this file's path has been remapped to `/rustc/$hash`,
1778 // we might be able to reverse that (also see comments above,
1779 // on `try_to_translate_virtual_to_real`).
ba9703b0
XL
1780 try_to_translate_virtual_to_real(&mut name);
1781
dfeec247
XL
1782 let source_length = (end_pos - start_pos).to_usize();
1783
1784 // Translate line-start positions and multibyte character
1785 // position into frame of reference local to file.
1786 // `SourceMap::new_imported_source_file()` will then translate those
1787 // coordinates to their new global frame of reference when the
1788 // offset of the SourceFile is known.
1789 for pos in &mut lines {
1790 *pos = *pos - start_pos;
1791 }
1792 for mbc in &mut multibyte_chars {
1793 mbc.pos = mbc.pos - start_pos;
1794 }
1795 for swc in &mut non_narrow_chars {
1796 *swc = *swc - start_pos;
1797 }
1798 for np in &mut normalized_pos {
1799 np.pos = np.pos - start_pos;
1800 }
62682a34 1801
ba9703b0 1802 let local_version = sess.source_map().new_imported_source_file(
dfeec247 1803 name,
dfeec247
XL
1804 src_hash,
1805 name_hash,
1806 source_length,
ba9703b0 1807 self.cnum,
dfeec247
XL
1808 lines,
1809 multibyte_chars,
1810 non_narrow_chars,
1811 normalized_pos,
ba9703b0
XL
1812 start_pos,
1813 end_pos,
dfeec247
XL
1814 );
1815 debug!(
1816 "CrateMetaData::imported_source_files alloc \
74b04a01
XL
1817 source_file {:?} original (start_pos {:?} end_pos {:?}) \
1818 translated (start_pos {:?} end_pos {:?})",
dfeec247
XL
1819 local_version.name,
1820 start_pos,
1821 end_pos,
1822 local_version.start_pos,
1823 local_version.end_pos
1824 );
e74abb32 1825
dfeec247
XL
1826 ImportedSourceFile {
1827 original_start_pos: start_pos,
1828 original_end_pos: end_pos,
1829 translated_source_file: local_version,
1830 }
1831 })
1832 .collect()
e74abb32
XL
1833 })
1834 }
74b04a01 1835}
0531ce1d 1836
74b04a01
XL
1837impl CrateMetadata {
1838 crate fn new(
1839 sess: &Session,
1840 blob: MetadataBlob,
1841 root: CrateRoot<'static>,
1842 raw_proc_macros: Option<&'static [ProcMacro]>,
1843 cnum: CrateNum,
1844 cnum_map: CrateNumMap,
3dfed10e 1845 dep_kind: CrateDepKind,
74b04a01
XL
1846 source: CrateSource,
1847 private_dep: bool,
1848 host_hash: Option<Svh>,
1849 ) -> CrateMetadata {
74b04a01
XL
1850 let trait_impls = root
1851 .impls
1852 .decode((&blob, sess))
1853 .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
1854 .collect();
1855 let alloc_decoding_state =
1856 AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
1857 let dependencies = Lock::new(cnum_map.iter().cloned().collect());
c295e0f8
XL
1858
1859 // Pre-decode the DefPathHash->DefIndex table. This is a cheap operation
1860 // that does not copy any data. It just does some data verification.
1861 let def_path_hash_map = root.def_path_hash_map.decode(&blob);
1862
74b04a01
XL
1863 CrateMetadata {
1864 blob,
1865 root,
74b04a01
XL
1866 trait_impls,
1867 raw_proc_macros,
f9f354fc 1868 source_map_import_info: OnceCell::new(),
c295e0f8 1869 def_path_hash_map,
136023e0 1870 expn_hash_map: Default::default(),
74b04a01 1871 alloc_decoding_state,
74b04a01
XL
1872 cnum,
1873 cnum_map,
1874 dependencies,
1875 dep_kind: Lock::new(dep_kind),
5099ac24 1876 source: Lrc::new(source),
74b04a01
XL
1877 private_dep,
1878 host_hash,
1879 extern_crate: Lock::new(None),
3dfed10e
XL
1880 hygiene_context: Default::default(),
1881 def_key_cache: Default::default(),
1882 def_path_hash_cache: Default::default(),
e74abb32 1883 }
b039eaaf 1884 }
60c5eb7d
XL
1885
1886 crate fn dependencies(&self) -> LockGuard<'_, Vec<CrateNum>> {
1887 self.dependencies.borrow()
1888 }
1889
1890 crate fn add_dependency(&self, cnum: CrateNum) {
1891 self.dependencies.borrow_mut().push(cnum);
1892 }
1893
1894 crate fn update_extern_crate(&self, new_extern_crate: ExternCrate) -> bool {
1895 let mut extern_crate = self.extern_crate.borrow_mut();
1896 let update = Some(new_extern_crate.rank()) > extern_crate.as_ref().map(ExternCrate::rank);
1897 if update {
1898 *extern_crate = Some(new_extern_crate);
1899 }
1900 update
1901 }
1902
1903 crate fn source(&self) -> &CrateSource {
5099ac24 1904 &*self.source
60c5eb7d
XL
1905 }
1906
3dfed10e 1907 crate fn dep_kind(&self) -> CrateDepKind {
60c5eb7d
XL
1908 *self.dep_kind.lock()
1909 }
1910
3dfed10e 1911 crate fn update_dep_kind(&self, f: impl FnOnce(CrateDepKind) -> CrateDepKind) {
60c5eb7d
XL
1912 self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind))
1913 }
1914
1915 crate fn panic_strategy(&self) -> PanicStrategy {
1916 self.root.panic_strategy
1917 }
1918
1919 crate fn needs_panic_runtime(&self) -> bool {
1920 self.root.needs_panic_runtime
1921 }
1922
1923 crate fn is_panic_runtime(&self) -> bool {
1924 self.root.panic_runtime
1925 }
1926
60c5eb7d
XL
1927 crate fn is_profiler_runtime(&self) -> bool {
1928 self.root.profiler_runtime
1929 }
1930
1931 crate fn needs_allocator(&self) -> bool {
1932 self.root.needs_allocator
1933 }
1934
1935 crate fn has_global_allocator(&self) -> bool {
1936 self.root.has_global_allocator
1937 }
1938
1939 crate fn has_default_lib_allocator(&self) -> bool {
1940 self.root.has_default_lib_allocator
1941 }
1942
1943 crate fn is_proc_macro_crate(&self) -> bool {
1944 self.root.is_proc_macro_crate()
1945 }
1946
1947 crate fn name(&self) -> Symbol {
1948 self.root.name
1949 }
1950
136023e0
XL
1951 crate fn stable_crate_id(&self) -> StableCrateId {
1952 self.root.stable_crate_id
60c5eb7d
XL
1953 }
1954
1955 crate fn hash(&self) -> Svh {
1956 self.root.hash
1957 }
74b04a01 1958
3dfed10e
XL
1959 fn num_def_ids(&self) -> usize {
1960 self.root.tables.def_keys.size()
1961 }
1962
74b04a01
XL
1963 fn local_def_id(&self, index: DefIndex) -> DefId {
1964 DefId { krate: self.cnum, index }
1965 }
1966
1967 // Translate a DefId from the current compilation environment to a DefId
1968 // for an external crate.
1969 fn reverse_translate_def_id(&self, did: DefId) -> Option<DefId> {
1970 for (local, &global) in self.cnum_map.iter_enumerated() {
1971 if global == did.krate {
1972 return Some(DefId { krate: local, index: did.index });
1973 }
1974 }
1975
1976 None
1977 }
a7813a04 1978}
e1599b0c
XL
1979
1980// Cannot be implemented on 'ProcMacro', as libproc_macro
74b04a01 1981// does not depend on librustc_ast
e1599b0c
XL
1982fn macro_kind(raw: &ProcMacro) -> MacroKind {
1983 match raw {
1984 ProcMacro::CustomDerive { .. } => MacroKind::Derive,
1985 ProcMacro::Attr { .. } => MacroKind::Attr,
dfeec247 1986 ProcMacro::Bang { .. } => MacroKind::Bang,
e1599b0c
XL
1987 }
1988}