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