Skip to main content

rustc_metadata/rmeta/
decoder.rs

1// Decoding metadata from a single crate's metadata
2
3use std::iter::TrustedLen;
4use std::path::{Path, PathBuf};
5use std::sync::{Arc, OnceLock};
6use std::{io, mem};
7
8pub(super) use cstore_impl::provide;
9use rustc_ast as ast;
10use rustc_attr_ir::CanonicalSymbols;
11use rustc_attr_ir::diagnostic_items::DiagnosticItems;
12use rustc_crate_store::{CrateSource, ExternCrate};
13use rustc_data_structures::fingerprint::Fingerprint;
14use rustc_data_structures::fx::FxIndexMap;
15use rustc_data_structures::owned_slice::OwnedSlice;
16use rustc_data_structures::sync::Lock;
17use rustc_data_structures::unhash::UnhashMap;
18use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
19use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
20use rustc_hir::Safety;
21use rustc_hir::def::Res;
22use rustc_hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE};
23use rustc_hir::definitions::{DefPath, DefPathData};
24use rustc_index::Idx;
25use rustc_middle::middle::lib_features::LibFeatures;
26use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
27use rustc_middle::ty::codec::{TyDecoder, forward_all_decoder_methods_to};
28use rustc_middle::ty::{RestrictionKind, Visibility};
29use rustc_proc_macro::bridge::client::Client as ProcMacroClient;
30use rustc_serialize::opaque::MemDecoder;
31use rustc_serialize::{Decodable, Decoder};
32use rustc_session::config::TargetModifier;
33use rustc_session::config::mitigation_coverage::DeniedPartialMitigation;
34use rustc_span::def_id::ModId;
35use rustc_span::hygiene::HygieneDecodeContext;
36use rustc_span::{
37    BlobDecoder, BytePos, ByteSymbol, DUMMY_SP, Pos, RemapPathScopeComponents, SpanData,
38    SpanDecoder, Symbol, SyntaxContext, bug, kw,
39};
40use tracing::debug;
41
42use crate::creader::CStore;
43use crate::eii::EiiMapEncodedKeyValue;
44use crate::rmeta::table::IsDefault;
45use crate::rmeta::*;
46
47mod cstore_impl;
48
49/// A reference to the raw binary version of crate metadata.
50/// This struct applies [`MemDecoder`]'s validation when constructed
51/// so that later constructions are guaranteed to succeed.
52pub(crate) struct MetadataBlob(OwnedSlice);
53
54impl std::ops::Deref for MetadataBlob {
55    type Target = [u8];
56
57    #[inline]
58    fn deref(&self) -> &[u8] {
59        &self.0[..]
60    }
61}
62
63impl MetadataBlob {
64    /// Runs the [`MemDecoder`] validation and if it passes, constructs a new [`MetadataBlob`].
65    pub(crate) fn new(slice: OwnedSlice) -> Result<Self, ()> {
66        if MemDecoder::new(&slice, 0).is_ok() { Ok(Self(slice)) } else { Err(()) }
67    }
68
69    /// Since this has passed the validation of [`MetadataBlob::new`], this returns bytes which are
70    /// known to pass the [`MemDecoder`] validation.
71    pub(crate) fn bytes(&self) -> &OwnedSlice {
72        &self.0
73    }
74}
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.
80pub(crate) type CrateNumMap = IndexVec<CrateNum, CrateNum>;
81
82/// Target modifiers - abi or exploit mitigations options that may cause unsoundness when mixed or
83/// partially enabled.
84pub(crate) type TargetModifiers = Vec<TargetModifier>;
85
86/// The set of mitigations that cannot be partially enabled (see
87/// [RFC 3855](https://github.com/rust-lang/rfcs/pull/3855)), but are currently enabled for this
88/// crate.
89pub(crate) type DeniedPartialMitigations = Vec<DeniedPartialMitigation>;
90
91pub(crate) struct CrateMetadata {
92    /// The primary crate data - binary metadata blob.
93    blob: MetadataBlob,
94
95    // --- Some data pre-decoded from the metadata blob, usually for performance ---
96    /// Data about the top-level items in a crate, as well as various crate-level metadata.
97    root: CrateRoot,
98    /// Crate-level metadata that is not in the SVH.
99    unhashed: CrateRootUnhashed,
100    /// Trait impl data.
101    /// FIXME: Used only from queries and can use query cache,
102    /// so pre-decoding can probably be avoided.
103    trait_impls: FxIndexMap<(u32, DefIndex), LazyArray<(DefIndex, Option<SimplifiedType>)>>,
104    /// Inherent impls which do not follow the normal coherence rules.
105    ///
106    /// These can be introduced using either `#![rustc_coherence_is_core]`
107    /// or `#[rustc_allow_incoherent_impl]`.
108    incoherent_impls: FxIndexMap<SimplifiedType, LazyArray<DefIndex>>,
109    /// Proc macro function pointers for this crate, if it's a proc macro crate.
110    raw_proc_macros: Option<&'static [ProcMacroClient]>,
111    /// Source maps for code from the crate.
112    source_map_import_info: Lock<Vec<Option<ImportedSourceFile>>>,
113    /// For every definition in this crate, maps its `DefPathHash` to its `DefIndex`.
114    def_path_hash_map: DefPathHashMapRef<'static>,
115    /// Likewise for ExpnHash.
116    expn_hash_map: OnceLock<UnhashMap<ExpnHash, ExpnIndex>>,
117    /// Used for decoding interpret::AllocIds in a cached & thread-safe manner.
118    alloc_decoding_state: AllocDecodingState,
119    /// Caches decoded `DefKey`s.
120    def_key_cache: Lock<FxHashMap<DefIndex, DefKey>>,
121
122    // --- Other significant crate properties ---
123    /// ID of this crate, from the current compilation session's point of view.
124    cnum: CrateNum,
125    /// Maps crate IDs as they are were seen from this crate's compilation sessions into
126    /// IDs as they are seen from the current compilation session.
127    cnum_map: CrateNumMap,
128    /// How to link (or not link) this crate to the currently compiled crate.
129    dep_kind: CrateDepKind,
130    /// Filesystem location of this crate.
131    source: Arc<CrateSource>,
132    /// Whether or not this crate should be consider a private dependency.
133    /// Used by the 'exported_private_dependencies' lint, and for determining
134    /// whether to emit suggestions that reference this crate.
135    private_dep: bool,
136    /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
137    host_hash: Option<Svh>,
138    /// The crate was used non-speculatively.
139    used: bool,
140
141    /// Additional data used for decoding `HygieneData` (e.g. `SyntaxContext`
142    /// and `ExpnId`).
143    /// Note that we store a `HygieneDecodeContext` for each `CrateMetadata`. This is
144    /// because `SyntaxContext` ids are not globally unique, so we need
145    /// to track which ids we've decoded on a per-crate basis.
146    hygiene_context: HygieneDecodeContext,
147
148    // --- Data used only for improving diagnostics ---
149    /// Information about the `extern crate` item or path that caused this crate to be loaded.
150    /// If this is `None`, then the crate was injected (e.g., by the allocator).
151    extern_crate: Option<ExternCrate>,
152}
153
154/// Holds information about a rustc_span::SourceFile imported from another crate.
155/// See `imported_source_file()` for more information.
156#[derive(#[automatically_derived]
impl ::core::clone::Clone for ImportedSourceFile {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            original_start_pos: ::core::clone::Clone::clone(&self.original_start_pos),
            original_end_pos: ::core::clone::Clone::clone(&self.original_end_pos),
            translated_source_file: ::core::clone::Clone::clone(&self.translated_source_file),
        }
    }
}Clone)]
157struct ImportedSourceFile {
158    /// This SourceFile's byte-offset within the source_map of its original crate
159    original_start_pos: rustc_span::BytePos,
160    /// The end of this SourceFile within the source_map of its original crate
161    original_end_pos: rustc_span::BytePos,
162    /// The imported SourceFile's representation within the local source_map
163    translated_source_file: Arc<rustc_span::SourceFile>,
164}
165
166/// Decode context used when we just have a blob of metadata from which we have to decode a header
167/// and [`CrateRoot`]. After that, [`MetadataDecodeContext`] can be used.
168/// Most notably, [`BlobDecodeContext]` doesn't implement [`SpanDecoder`]
169pub(super) struct BlobDecodeContext<'a> {
170    opaque: MemDecoder<'a>,
171    blob: &'a MetadataBlob,
172    lazy_state: LazyState,
173}
174
175/// This trait abstracts over decoders that can decode lazy values using [`LazyState`]:
176///
177/// - [`LazyValue`]
178/// - [`LazyArray`]
179/// - [`LazyTable`]
180pub(super) trait LazyDecoder: BlobDecoder {
181    fn set_lazy_state(&mut self, state: LazyState);
182    fn get_lazy_state(&self) -> LazyState;
183
184    fn read_lazy<T>(&mut self) -> LazyValue<T> {
185        self.read_lazy_offset_then(|pos| LazyValue::from_position(pos))
186    }
187
188    fn read_lazy_array<T>(&mut self, len: usize) -> LazyArray<T> {
189        self.read_lazy_offset_then(|pos| LazyArray::from_position_and_num_elems(pos, len))
190    }
191
192    fn read_lazy_table<I, T>(&mut self, width: usize, len: usize) -> LazyTable<I, T> {
193        self.read_lazy_offset_then(|pos| LazyTable::from_position_and_encoded_size(pos, width, len))
194    }
195
196    #[inline]
197    fn read_lazy_offset_then<T>(&mut self, f: impl Fn(NonZero<usize>) -> T) -> T {
198        let distance = self.read_usize();
199        let position = match self.get_lazy_state() {
200            LazyState::NoNode => ::rustc_span::macros::bug_impl(None,
    format_args!("read_lazy_with_meta: outside of a metadata node"),
    Location::caller())bug!("read_lazy_with_meta: outside of a metadata node"),
201            LazyState::NodeStart(start) => {
202                let start = start.get();
203                if !(distance <= start) {
    ::core::panicking::panic("assertion failed: distance <= start")
};assert!(distance <= start);
204                start - distance
205            }
206            LazyState::Previous(last_pos) => last_pos.get() + distance,
207        };
208        let position = NonZero::new(position).unwrap();
209        self.set_lazy_state(LazyState::Previous(position));
210        f(position)
211    }
212}
213
214impl<'a> LazyDecoder for BlobDecodeContext<'a> {
215    fn set_lazy_state(&mut self, state: LazyState) {
216        self.lazy_state = state;
217    }
218
219    fn get_lazy_state(&self) -> LazyState {
220        self.lazy_state
221    }
222}
223
224/// This is the decode context used when crate metadata was already read.
225/// Decoding of some types, like `Span` require some information to already been read.
226/// Can be constructed from a [`TyCtxt`] and [`CrateMetadata`] (see impls of the [`MetaDecoder`]
227/// trait).
228pub(super) struct MetadataDecodeContext<'a, 'tcx> {
229    blob_decoder: BlobDecodeContext<'a>,
230    cdata: &'a CrateMetadata,
231    tcx: TyCtxt<'tcx>,
232
233    // Used for decoding interpret::AllocIds in a cached & thread-safe manner.
234    alloc_decoding_session: AllocDecodingSession<'a>,
235}
236
237impl<'a, 'tcx> LazyDecoder for MetadataDecodeContext<'a, 'tcx> {
238    fn set_lazy_state(&mut self, state: LazyState) {
239        self.blob_decoder.lazy_state = state;
240    }
241
242    fn get_lazy_state(&self) -> LazyState {
243        self.blob_decoder.lazy_state
244    }
245}
246
247pub(super) trait MetaBlob<'a>: Copy {
248    fn blob(&self) -> &'a MetadataBlob;
249}
250
251pub(super) trait MetaDecoder: Copy {
252    type Context: BlobDecoder + LazyDecoder;
253
254    fn decoder(self, pos: usize) -> Self::Context;
255}
256
257impl<'a> MetaBlob<'a> for &'a MetadataBlob {
258    fn blob(&self) -> &'a MetadataBlob {
259        self
260    }
261}
262
263impl<'a> MetaDecoder for &'a MetadataBlob {
264    type Context = BlobDecodeContext<'a>;
265
266    fn decoder(self, pos: usize) -> Self::Context {
267        BlobDecodeContext {
268            // FIXME: This unwrap should never panic because we check that it won't when creating
269            // `MetadataBlob`. Ideally we'd just have a `MetadataDecoder` and hand out subslices of
270            // it as we do elsewhere in the compiler using `MetadataDecoder::split_at`. But we own
271            // the data for the decoder so holding onto the `MemDecoder` too would make us a
272            // self-referential struct which is downright goofy because `MetadataBlob` is already
273            // self-referential. Probably `MemDecoder` should contain an `OwnedSlice`, but that
274            // demands a significant refactoring due to our crate graph.
275            opaque: MemDecoder::new(self, pos).unwrap(),
276            lazy_state: LazyState::NoNode,
277            blob: self.blob(),
278        }
279    }
280}
281
282impl<'a> MetaBlob<'a> for &'a CrateMetadata {
283    fn blob(&self) -> &'a MetadataBlob {
284        &self.blob
285    }
286}
287
288impl<'a, 'tcx> MetaDecoder for (&'a CrateMetadata, TyCtxt<'tcx>) {
289    type Context = MetadataDecodeContext<'a, 'tcx>;
290
291    fn decoder(self, pos: usize) -> MetadataDecodeContext<'a, 'tcx> {
292        MetadataDecodeContext {
293            blob_decoder: self.0.blob().decoder(pos),
294            cdata: self.0,
295            tcx: self.1,
296            alloc_decoding_session: self.0.alloc_decoding_state.new_decoding_session(),
297        }
298    }
299}
300
301impl<T: ParameterizedOverTcx> LazyValue<T> {
302    #[inline]
303    fn decode<'tcx, M: MetaDecoder>(self, metadata: M) -> T::Value<'tcx>
304    where
305        T::Value<'tcx>: Decodable<M::Context>,
306    {
307        let mut dcx = metadata.decoder(self.position.get());
308        dcx.set_lazy_state(LazyState::NodeStart(self.position));
309        T::Value::decode(&mut dcx)
310    }
311}
312
313struct DecodeIterator<T, D> {
314    elem_counter: std::ops::Range<usize>,
315    dcx: D,
316    _phantom: PhantomData<fn() -> T>,
317}
318
319impl<D: Decoder, T: Decodable<D>> Iterator for DecodeIterator<T, D> {
320    type Item = T;
321
322    #[inline(always)]
323    fn next(&mut self) -> Option<Self::Item> {
324        self.elem_counter.next().map(|_| T::decode(&mut self.dcx))
325    }
326
327    #[inline(always)]
328    fn size_hint(&self) -> (usize, Option<usize>) {
329        self.elem_counter.size_hint()
330    }
331}
332
333impl<D: Decoder, T: Decodable<D>> ExactSizeIterator for DecodeIterator<T, D> {
334    fn len(&self) -> usize {
335        self.elem_counter.len()
336    }
337}
338
339unsafe impl<D: Decoder, T: Decodable<D>> TrustedLen for DecodeIterator<T, D> {}
340
341impl<T: ParameterizedOverTcx> LazyArray<T> {
342    #[inline]
343    fn decode<'tcx, M: MetaDecoder>(self, metadata: M) -> DecodeIterator<T::Value<'tcx>, M::Context>
344    where
345        T::Value<'tcx>: Decodable<M::Context>,
346    {
347        let mut dcx = metadata.decoder(self.position.get());
348        dcx.set_lazy_state(LazyState::NodeStart(self.position));
349        DecodeIterator { elem_counter: (0..self.num_elems), dcx, _phantom: PhantomData }
350    }
351}
352
353impl<'a, 'tcx> MetadataDecodeContext<'a, 'tcx> {
354    #[inline]
355    fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
356        self.cdata.map_encoded_cnum_to_current(cnum)
357    }
358}
359
360impl<'a> BlobDecodeContext<'a> {
361    #[inline]
362    pub(crate) fn blob(&self) -> &'a MetadataBlob {
363        self.blob
364    }
365
366    fn decode_symbol_or_byte_symbol<S>(
367        &mut self,
368        new_from_index: impl Fn(u32) -> S,
369        read_and_intern_str_or_byte_str_this: impl Fn(&mut Self) -> S,
370        read_and_intern_str_or_byte_str_opaque: impl Fn(&mut MemDecoder<'a>) -> S,
371    ) -> S {
372        let tag = self.read_u8();
373
374        match tag {
375            SYMBOL_STR => read_and_intern_str_or_byte_str_this(self),
376            SYMBOL_OFFSET => {
377                // read str offset
378                let pos = self.read_usize();
379
380                // move to str offset and read
381                self.opaque.with_position(pos, |d| read_and_intern_str_or_byte_str_opaque(d))
382            }
383            SYMBOL_PREDEFINED => new_from_index(self.read_u32()),
384            _ => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
385        }
386    }
387}
388
389impl<'a, 'tcx> TyDecoder<'tcx> for MetadataDecodeContext<'a, 'tcx> {
390    const CLEAR_CROSS_CRATE: bool = true;
391
392    fn cached_ty_for_shorthand<F>(&mut self, shorthand: usize, or_insert_with: F) -> Ty<'tcx>
393    where
394        F: FnOnce(&mut Self) -> Ty<'tcx>,
395    {
396        let tcx = self.tcx;
397
398        let key = ty::CReaderCacheKey { cnum: Some(self.cdata.cnum), pos: shorthand };
399
400        if let Some(&ty) = tcx.caches.ty_rcache.borrow().get(&key) {
401            return ty;
402        }
403
404        let ty = or_insert_with(self);
405        tcx.caches.ty_rcache.borrow_mut().insert(key, ty);
406        ty
407    }
408
409    fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
410    where
411        F: FnOnce(&mut Self) -> R,
412    {
413        let new_opaque = self.blob_decoder.opaque.split_at(pos);
414        let old_opaque = mem::replace(&mut self.blob_decoder.opaque, new_opaque);
415        let old_state = mem::replace(&mut self.blob_decoder.lazy_state, LazyState::NoNode);
416        let r = f(self);
417        self.blob_decoder.opaque = old_opaque;
418        self.blob_decoder.lazy_state = old_state;
419        r
420    }
421
422    fn decode_alloc_id(&mut self) -> rustc_middle::mir::interpret::AllocId {
423        let ads = self.alloc_decoding_session;
424        ads.decode_alloc_id(self)
425    }
426}
427
428impl<'a, 'tcx> rustc_middle::ty::InternerDecoder for MetadataDecodeContext<'a, 'tcx> {
429    type Interner = TyCtxt<'tcx>;
430
431    #[inline]
432    fn interner(&self) -> TyCtxt<'tcx> {
433        self.tcx
434    }
435}
436
437impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for ExpnIndex {
438    #[inline]
439    fn decode(d: &mut MetadataDecodeContext<'a, 'tcx>) -> ExpnIndex {
440        ExpnIndex::from_u32(d.read_u32())
441    }
442}
443
444impl<'a, 'tcx> SpanDecoder for MetadataDecodeContext<'a, 'tcx> {
445    fn decode_attr_id(&mut self) -> rustc_span::AttrId {
446        self.tcx.sess.psess.attr_id_generator.mk_attr_id()
447    }
448
449    fn decode_crate_num(&mut self) -> CrateNum {
450        let cnum = CrateNum::from_u32(self.read_u32());
451        self.map_encoded_cnum_to_current(cnum)
452    }
453
454    fn decode_def_id(&mut self) -> DefId {
455        DefId { krate: Decodable::decode(self), index: Decodable::decode(self) }
456    }
457
458    fn decode_syntax_context(&mut self) -> SyntaxContext {
459        let cdata = self.cdata;
460        let tcx = self.tcx;
461
462        let cname = cdata.root.name();
463        rustc_span::hygiene::decode_syntax_context(self, &cdata.hygiene_context, |_, id| {
464            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs:464",
                        "rustc_metadata::rmeta::decoder", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs"),
                        ::tracing_core::__macro_support::Option::Some(464u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_metadata::rmeta::decoder"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("SpecializedDecoder<SyntaxContext>: decoding {0}",
                                                    id) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
465            cdata
466                .root
467                .syntax_contexts
468                .get(cdata, id)
469                .unwrap_or_else(|| {
    ::core::panicking::panic_fmt(format_args!("Missing SyntaxContext {0:?} for crate {1:?}",
            id, cname));
}panic!("Missing SyntaxContext {id:?} for crate {cname:?}"))
470                .decode((cdata, tcx))
471        })
472    }
473
474    fn decode_expn_id(&mut self) -> ExpnId {
475        let tcx = self.tcx;
476        let cnum = CrateNum::decode(self);
477        let index = u32::decode(self);
478
479        let expn_id = rustc_span::hygiene::decode_expn_id(cnum, index, |expn_id| {
480            let ExpnId { krate: cnum, local_id: index } = expn_id;
481            // Lookup local `ExpnData`s in our own crate data. Foreign `ExpnData`s
482            // are stored in the owning crate, to avoid duplication.
483            if true {
    {
        match (&cnum, &LOCAL_CRATE) {
            (left_val, right_val) => {
                if *left_val == *right_val {
                    let kind = ::core::panicking::AssertKind::Ne;
                    ::core::panicking::assert_failed(kind, &*left_val,
                        &*right_val, ::core::option::Option::None);
                }
            }
        }
    };
};debug_assert_ne!(cnum, LOCAL_CRATE);
484            let cstore;
485            let cdata = if cnum == self.cdata.cnum {
486                self.cdata
487            } else {
488                cstore = CStore::from_tcx(tcx);
489                cstore.get_crate_data(cnum)
490            };
491            let expn_data = cdata.root.expn_data.get(cdata, index).unwrap().decode((cdata, tcx));
492            let expn_hash = cdata.root.expn_hashes.get(cdata, index).unwrap().decode((cdata, tcx));
493            (expn_data, expn_hash)
494        });
495        expn_id
496    }
497
498    fn decode_span(&mut self) -> Span {
499        let start = self.position();
500        let tag = SpanTag(self.peek_byte());
501        let data = if tag.kind() == SpanKind::Indirect {
502            // Skip past the tag we just peek'd.
503            self.read_u8();
504            // indirect tag lengths are safe to access, since they're (0, 8)
505            let bytes_needed = tag.length().unwrap().0 as usize;
506            let mut total = [0u8; usize::BITS as usize / 8];
507            total[..bytes_needed].copy_from_slice(self.read_raw_bytes(bytes_needed));
508            let offset_or_position = usize::from_le_bytes(total);
509            let position = if tag.is_relative_offset() {
510                start - offset_or_position
511            } else {
512                offset_or_position
513            };
514            self.with_position(position, SpanData::decode)
515        } else {
516            SpanData::decode(self)
517        };
518        data.span()
519    }
520}
521
522impl<'a, 'tcx> BlobDecoder for MetadataDecodeContext<'a, 'tcx> {
523    fn decode_def_index(&mut self) -> DefIndex {
524        self.blob_decoder.decode_def_index()
525    }
526    fn decode_symbol(&mut self) -> Symbol {
527        self.blob_decoder.decode_symbol()
528    }
529
530    fn decode_byte_symbol(&mut self) -> ByteSymbol {
531        self.blob_decoder.decode_byte_symbol()
532    }
533}
534
535impl<'a> BlobDecoder for BlobDecodeContext<'a> {
536    fn decode_def_index(&mut self) -> DefIndex {
537        DefIndex::from_u32(self.read_u32())
538    }
539    fn decode_symbol(&mut self) -> Symbol {
540        self.decode_symbol_or_byte_symbol(
541            Symbol::new,
542            |this| Symbol::intern(this.read_str()),
543            |opaque| Symbol::intern(opaque.read_str()),
544        )
545    }
546
547    fn decode_byte_symbol(&mut self) -> ByteSymbol {
548        self.decode_symbol_or_byte_symbol(
549            ByteSymbol::new,
550            |this| ByteSymbol::intern(this.read_byte_str()),
551            |opaque| ByteSymbol::intern(opaque.read_byte_str()),
552        )
553    }
554}
555
556impl<'a, 'tcx> Decodable<MetadataDecodeContext<'a, 'tcx>> for SpanData {
557    fn decode(decoder: &mut MetadataDecodeContext<'a, 'tcx>) -> SpanData {
558        let tag = SpanTag::decode(decoder);
559        let ctxt = tag.context().unwrap_or_else(|| SyntaxContext::decode(decoder));
560
561        if tag.kind() == SpanKind::Partial {
562            return DUMMY_SP.with_ctxt(ctxt).data();
563        }
564
565        if true {
    if !(tag.kind() == SpanKind::Local || tag.kind() == SpanKind::Foreign) {
        ::core::panicking::panic("assertion failed: tag.kind() == SpanKind::Local || tag.kind() == SpanKind::Foreign")
    };
};debug_assert!(tag.kind() == SpanKind::Local || tag.kind() == SpanKind::Foreign);
566
567        let lo = BytePos::decode(decoder);
568        let len = tag.length().unwrap_or_else(|| BytePos::decode(decoder));
569        let hi = lo + len;
570
571        let tcx = decoder.tcx;
572
573        // Index of the file in the corresponding crate's list of encoded files.
574        let metadata_index = u32::decode(decoder);
575
576        // There are two possibilities here:
577        // 1. This is a 'local span', which is located inside a `SourceFile`
578        // that came from this crate. In this case, we use the source map data
579        // encoded in this crate. This branch should be taken nearly all of the time.
580        // 2. This is a 'foreign span', which is located inside a `SourceFile`
581        // that came from a *different* crate (some crate upstream of the one
582        // whose metadata we're looking at). For example, consider this dependency graph:
583        //
584        // A -> B -> C
585        //
586        // Suppose that we're currently compiling crate A, and start deserializing
587        // metadata from crate B. When we deserialize a Span from crate B's metadata,
588        // there are two possibilities:
589        //
590        // 1. The span references a file from crate B. This makes it a 'local' span,
591        // which means that we can use crate B's serialized source map information.
592        // 2. The span references a file from crate C. This makes it a 'foreign' span,
593        // which means we need to use Crate *C* (not crate B) to determine the source
594        // map information. We only record source map information for a file in the
595        // crate that 'owns' it, so deserializing a Span may require us to look at
596        // a transitive dependency.
597        //
598        // When we encode a foreign span, we adjust its 'lo' and 'high' values
599        // to be based on the *foreign* crate (e.g. crate C), not the crate
600        // we are writing metadata for (e.g. crate B). This allows us to
601        // treat the 'local' and 'foreign' cases almost identically during deserialization:
602        // we can call `imported_source_file` for the proper crate, and binary search
603        // through the returned slice using our span.
604        let source_file = if tag.kind() == SpanKind::Local {
605            decoder.cdata.imported_source_file(tcx, metadata_index)
606        } else {
607            // When we encode a proc-macro crate, all `Span`s should be encoded
608            // with `TAG_VALID_SPAN_LOCAL`
609            if decoder.cdata.root.is_proc_macro_crate() {
610                // Decode `CrateNum` as u32 - using `CrateNum::decode` will ICE
611                // since we don't have `cnum_map` populated.
612                let cnum = u32::decode(decoder);
613                {
    ::core::panicking::panic_fmt(format_args!("Decoding of crate {0:?} tried to access proc-macro dep {1:?}",
            decoder.cdata.root.header.name, cnum));
};panic!(
614                    "Decoding of crate {:?} tried to access proc-macro dep {:?}",
615                    decoder.cdata.root.header.name, cnum
616                );
617            }
618            // tag is TAG_VALID_SPAN_FOREIGN, checked by `debug_assert` above
619            let cnum = CrateNum::decode(decoder);
620            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs:620",
                        "rustc_metadata::rmeta::decoder", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs"),
                        ::tracing_core::__macro_support::Option::Some(620u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_metadata::rmeta::decoder"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("SpecializedDecoder<Span>::specialized_decode: loading source files from cnum {0:?}",
                                                    cnum) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
621                "SpecializedDecoder<Span>::specialized_decode: loading source files from cnum {:?}",
622                cnum
623            );
624
625            let cstore = CStore::from_tcx(tcx);
626            let foreign_cdata = cstore.get_crate_data(cnum);
627            foreign_cdata.imported_source_file(tcx, metadata_index)
628        };
629
630        // Make sure our span is well-formed.
631        if true {
    if !(lo + source_file.original_start_pos <= source_file.original_end_pos)
        {
        {
            ::core::panicking::panic_fmt(format_args!("Malformed encoded span: lo={0:?} source_file.original_start_pos={1:?} source_file.original_end_pos={2:?}",
                    lo, source_file.original_start_pos,
                    source_file.original_end_pos));
        }
    };
};debug_assert!(
632            lo + source_file.original_start_pos <= source_file.original_end_pos,
633            "Malformed encoded span: lo={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
634            lo,
635            source_file.original_start_pos,
636            source_file.original_end_pos
637        );
638
639        // Make sure we correctly filtered out invalid spans during encoding.
640        if true {
    if !(hi + source_file.original_start_pos <= source_file.original_end_pos)
        {
        {
            ::core::panicking::panic_fmt(format_args!("Malformed encoded span: hi={0:?} source_file.original_start_pos={1:?} source_file.original_end_pos={2:?}",
                    hi, source_file.original_start_pos,
                    source_file.original_end_pos));
        }
    };
};debug_assert!(
641            hi + source_file.original_start_pos <= source_file.original_end_pos,
642            "Malformed encoded span: hi={:?} source_file.original_start_pos={:?} source_file.original_end_pos={:?}",
643            hi,
644            source_file.original_start_pos,
645            source_file.original_end_pos
646        );
647
648        let lo = lo + source_file.translated_source_file.start_pos;
649        let hi = hi + source_file.translated_source_file.start_pos;
650
651        // Do not try to decode parent for foreign spans (it wasn't encoded in the first place).
652        SpanData { lo, hi, ctxt, parent: None }
653    }
654}
655
656impl<D: LazyDecoder, T> Decodable<D> for LazyValue<T> {
657    fn decode(decoder: &mut D) -> Self {
658        decoder.read_lazy()
659    }
660}
661
662impl<D: LazyDecoder, T> Decodable<D> for LazyArray<T> {
663    #[inline]
664    fn decode(decoder: &mut D) -> Self {
665        let len = decoder.read_usize();
666        if len == 0 { LazyArray::default() } else { decoder.read_lazy_array(len) }
667    }
668}
669
670impl<I: Idx, D: LazyDecoder, T> Decodable<D> for LazyTable<I, T> {
671    fn decode(decoder: &mut D) -> Self {
672        let width = decoder.read_usize();
673        let len = decoder.read_usize();
674        decoder.read_lazy_table(width, len)
675    }
676}
677
678impl<'a, 'tcx> Decoder for MetadataDecodeContext<'a, 'tcx> {
679    #[inline]
fn read_usize(&mut self) -> usize { self.blob_decoder.opaque.read_usize() }
#[inline]
fn read_u128(&mut self) -> u128 { self.blob_decoder.opaque.read_u128() }
#[inline]
fn read_u64(&mut self) -> u64 { self.blob_decoder.opaque.read_u64() }
#[inline]
fn read_u32(&mut self) -> u32 { self.blob_decoder.opaque.read_u32() }
#[inline]
fn read_u16(&mut self) -> u16 { self.blob_decoder.opaque.read_u16() }
#[inline]
fn read_u8(&mut self) -> u8 { self.blob_decoder.opaque.read_u8() }
#[inline]
fn read_isize(&mut self) -> isize { self.blob_decoder.opaque.read_isize() }
#[inline]
fn read_i128(&mut self) -> i128 { self.blob_decoder.opaque.read_i128() }
#[inline]
fn read_i64(&mut self) -> i64 { self.blob_decoder.opaque.read_i64() }
#[inline]
fn read_i32(&mut self) -> i32 { self.blob_decoder.opaque.read_i32() }
#[inline]
fn read_i16(&mut self) -> i16 { self.blob_decoder.opaque.read_i16() }
#[inline]
fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
    self.blob_decoder.opaque.read_raw_bytes(len)
}
#[inline]
fn peek_byte(&self) -> u8 { self.blob_decoder.opaque.peek_byte() }
#[inline]
fn position(&self) -> usize { self.blob_decoder.opaque.position() }forward_all_decoder_methods_to!(|self| self.blob_decoder.opaque);
680}
681
682impl<'a> Decoder for BlobDecodeContext<'a> {
683    #[inline]
fn read_usize(&mut self) -> usize { self.opaque.read_usize() }
#[inline]
fn read_u128(&mut self) -> u128 { self.opaque.read_u128() }
#[inline]
fn read_u64(&mut self) -> u64 { self.opaque.read_u64() }
#[inline]
fn read_u32(&mut self) -> u32 { self.opaque.read_u32() }
#[inline]
fn read_u16(&mut self) -> u16 { self.opaque.read_u16() }
#[inline]
fn read_u8(&mut self) -> u8 { self.opaque.read_u8() }
#[inline]
fn read_isize(&mut self) -> isize { self.opaque.read_isize() }
#[inline]
fn read_i128(&mut self) -> i128 { self.opaque.read_i128() }
#[inline]
fn read_i64(&mut self) -> i64 { self.opaque.read_i64() }
#[inline]
fn read_i32(&mut self) -> i32 { self.opaque.read_i32() }
#[inline]
fn read_i16(&mut self) -> i16 { self.opaque.read_i16() }
#[inline]
fn read_raw_bytes(&mut self, len: usize) -> &[u8] {
    self.opaque.read_raw_bytes(len)
}
#[inline]
fn peek_byte(&self) -> u8 { self.opaque.peek_byte() }
#[inline]
fn position(&self) -> usize { self.opaque.position() }forward_all_decoder_methods_to!(|self| self.opaque);
684}
685
686impl MetadataBlob {
687    pub(crate) fn check_compatibility(
688        &self,
689        cfg_version: &'static str,
690    ) -> Result<(), Option<String>> {
691        if !self.starts_with(METADATA_HEADER) {
692            if self.starts_with(b"rust") {
693                return Err(Some("<unknown rustc version>".to_owned()));
694            }
695            return Err(None);
696        }
697
698        let found_version =
699            LazyValue::<String>::from_position(NonZero::new(VERSION_OFFSET).unwrap()).decode(self);
700        if rustc_version(cfg_version) != found_version {
701            return Err(Some(found_version));
702        }
703
704        Ok(())
705    }
706
707    fn root_pos(&self) -> NonZero<usize> {
708        let pos_bytes = self[ROOT_POS_OFFSET..][..8].try_into().unwrap();
709        let pos = u64::from_le_bytes(pos_bytes);
710        NonZero::new(pos as usize).unwrap()
711    }
712
713    fn unhashed_pos(&self) -> NonZero<usize> {
714        let pos_bytes = self[UNHASHED_POS_OFFSET..][..8].try_into().unwrap();
715        let pos = u64::from_le_bytes(pos_bytes);
716        NonZero::new(pos as usize).unwrap()
717    }
718
719    pub(crate) fn get_header(&self) -> CrateHeader {
720        let pos = self.root_pos();
721        LazyValue::<CrateHeader>::from_position(pos).decode(self)
722    }
723
724    pub(crate) fn get_root(&self) -> CrateRoot {
725        let pos = self.root_pos();
726        LazyValue::<CrateRoot>::from_position(pos).decode(self)
727    }
728
729    pub(crate) fn get_root_unhashed(&self) -> CrateRootUnhashed {
730        let pos = self.unhashed_pos();
731        LazyValue::<CrateRootUnhashed>::from_position(pos).decode(self)
732    }
733
734    pub(crate) fn get_dep_extra_filenames(&self) -> IndexVec<CrateNum, String> {
735        self.get_root_unhashed().dep_extra_filenames
736    }
737
738    pub(crate) fn get_crate_hash(&self) -> Svh {
739        let bytes: [u8; CRATE_HASH_LEN] =
740            self[CRATE_HASH_OFFSET..][..CRATE_HASH_LEN].try_into().unwrap();
741        Svh::new(Fingerprint::from_le_bytes(bytes))
742    }
743
744    pub(crate) fn list_crate_metadata(
745        &self,
746        out: &mut dyn io::Write,
747        ls_kinds: &[String],
748    ) -> io::Result<()> {
749        let root = self.get_root();
750        let extra_filename = self.get_root_unhashed().extra_filename;
751
752        let all_ls_kinds = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        ["root".to_owned(), "lang_items".to_owned(), "features".to_owned(),
                "items".to_owned(), "target_modifiers".to_owned()]))vec![
753            "root".to_owned(),
754            "lang_items".to_owned(),
755            "features".to_owned(),
756            "items".to_owned(),
757            "target_modifiers".to_owned(),
758        ];
759        let ls_kinds = if ls_kinds.contains(&"all".to_owned()) { &all_ls_kinds } else { ls_kinds };
760
761        for kind in ls_kinds {
762            match &**kind {
763                "root" => {
764                    out.write_fmt(format_args!("Crate info:\n"))writeln!(out, "Crate info:")?;
765                    out.write_fmt(format_args!("name {0}{1}\n", root.name(), extra_filename))writeln!(out, "name {}{}", root.name(), extra_filename)?;
766                    out.write_fmt(format_args!("hash {0} stable_crate_id {1:?}\n",
        self.get_crate_hash(), root.stable_crate_id))writeln!(
767                        out,
768                        "hash {} stable_crate_id {:?}",
769                        self.get_crate_hash(),
770                        root.stable_crate_id
771                    )?;
772                    out.write_fmt(format_args!("proc_macro {0:?}\n",
        root.proc_macro_data.is_some()))writeln!(out, "proc_macro {:?}", root.proc_macro_data.is_some())?;
773                    out.write_fmt(format_args!("triple {0}\n", root.header.triple.tuple()))writeln!(out, "triple {}", root.header.triple.tuple())?;
774                    out.write_fmt(format_args!("edition {0}\n", root.edition))writeln!(out, "edition {}", root.edition)?;
775                    out.write_fmt(format_args!("symbol_mangling_version {0:?}\n",
        root.symbol_mangling_version))writeln!(out, "symbol_mangling_version {:?}", root.symbol_mangling_version)?;
776                    out.write_fmt(format_args!("required_panic_strategy {0:?} panic_in_drop_strategy {1:?}\n",
        root.required_panic_strategy, root.panic_in_drop_strategy))writeln!(
777                        out,
778                        "required_panic_strategy {:?} panic_in_drop_strategy {:?}",
779                        root.required_panic_strategy, root.panic_in_drop_strategy
780                    )?;
781                    out.write_fmt(format_args!("has_global_allocator {0} has_alloc_error_handler {1} has_panic_handler {2} has_default_lib_allocator {3}\n",
        root.has_global_allocator, root.has_alloc_error_handler,
        root.has_panic_handler, root.has_default_lib_allocator))writeln!(
782                        out,
783                        "has_global_allocator {} has_alloc_error_handler {} has_panic_handler {} has_default_lib_allocator {}",
784                        root.has_global_allocator,
785                        root.has_alloc_error_handler,
786                        root.has_panic_handler,
787                        root.has_default_lib_allocator
788                    )?;
789                    out.write_fmt(format_args!("compiler_builtins {0} needs_allocator {1} needs_panic_runtime {2} no_builtins {3} panic_runtime {4} profiler_runtime {5}\n",
        root.compiler_builtins, root.needs_allocator,
        root.needs_panic_runtime, root.no_builtins, root.panic_runtime,
        root.profiler_runtime))writeln!(
790                        out,
791                        "compiler_builtins {} needs_allocator {} needs_panic_runtime {} no_builtins {} panic_runtime {} profiler_runtime {}",
792                        root.compiler_builtins,
793                        root.needs_allocator,
794                        root.needs_panic_runtime,
795                        root.no_builtins,
796                        root.panic_runtime,
797                        root.profiler_runtime
798                    )?;
799
800                    out.write_fmt(format_args!("=External Dependencies=\n"))writeln!(out, "=External Dependencies=")?;
801                    let dylib_dependency_formats =
802                        root.dylib_dependency_formats.decode(self).collect::<Vec<_>>();
803                    // `extra_filename` is stored outside the hashed root; see
804                    // `CrateRootUnhashed::dep_extra_filenames`.
805                    let dep_extra_filenames = self.get_dep_extra_filenames();
806                    for (i, dep) in root.crate_deps.decode(self).enumerate() {
807                        let CrateDep { name, hash, host_hash, kind, is_private } = dep;
808                        let number = i + 1;
809                        let extra_filename = dep_extra_filenames
810                            .get(CrateNum::new(number))
811                            .map_or("", |name| name.as_str());
812
813                        out.write_fmt(format_args!("{2} {3}{4} hash {5} host_hash {6:?} kind {7:?} {0}{1}\n",
        if is_private { "private" } else { "public" },
        if dylib_dependency_formats.is_empty() {
            String::new()
        } else {
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!(" linkage {0:?}",
                            dylib_dependency_formats[i]))
                })
        }, number, name, extra_filename, hash, host_hash, kind))writeln!(
814                            out,
815                            "{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}{linkage}",
816                            privacy = if is_private { "private" } else { "public" },
817                            linkage = if dylib_dependency_formats.is_empty() {
818                                String::new()
819                            } else {
820                                format!(" linkage {:?}", dylib_dependency_formats[i])
821                            }
822                        )?;
823                    }
824                    out.write_fmt(format_args!("\n"))write!(out, "\n")?;
825                }
826
827                "lang_items" => {
828                    out.write_fmt(format_args!("=Lang items=\n"))writeln!(out, "=Lang items=")?;
829                    for (id, lang_item) in root.lang_items.decode(self) {
830                        out.write_fmt(format_args!("{0} = crate{1}\n", lang_item.name(),
        DefPath::make(LOCAL_CRATE, id,
                |parent|
                    root.tables.def_keys.get(self,
                                parent).unwrap().decode(self)).to_string_no_crate_verbose()))writeln!(
831                            out,
832                            "{} = crate{}",
833                            lang_item.name(),
834                            DefPath::make(LOCAL_CRATE, id, |parent| root
835                                .tables
836                                .def_keys
837                                .get(self, parent)
838                                .unwrap()
839                                .decode(self))
840                            .to_string_no_crate_verbose()
841                        )?;
842                    }
843                    for lang_item in root.lang_items_missing.decode(self) {
844                        out.write_fmt(format_args!("{0} = <missing>\n", lang_item.name()))writeln!(out, "{} = <missing>", lang_item.name())?;
845                    }
846                    out.write_fmt(format_args!("\n"))write!(out, "\n")?;
847                }
848
849                "features" => {
850                    out.write_fmt(format_args!("=Lib features=\n"))writeln!(out, "=Lib features=")?;
851                    for (feature, since) in root.lib_features.decode(self) {
852                        out.write_fmt(format_args!("{0}{1}\n", feature,
        if let FeatureStability::AcceptedSince(since) = since {
            ::alloc::__export::must_use({
                    ::alloc::fmt::format(format_args!(" since {0}", since))
                })
        } else { String::new() }))writeln!(
853                            out,
854                            "{}{}",
855                            feature,
856                            if let FeatureStability::AcceptedSince(since) = since {
857                                format!(" since {since}")
858                            } else {
859                                String::new()
860                            }
861                        )?;
862                    }
863                    out.write_fmt(format_args!("\n"))write!(out, "\n")?;
864                }
865
866                "items" => {
867                    out.write_fmt(format_args!("=Items=\n"))writeln!(out, "=Items=")?;
868
869                    fn print_item(
870                        blob: &MetadataBlob,
871                        out: &mut dyn io::Write,
872                        item: DefIndex,
873                        indent: usize,
874                    ) -> io::Result<()> {
875                        let root = blob.get_root();
876
877                        let def_kind = root.tables.def_kind.get(blob, item).unwrap();
878                        let def_key = root.tables.def_keys.get(blob, item).unwrap().decode(blob);
879                        #[allow(rustc::symbol_intern_string_literal)]
880                        let def_name = if item == CRATE_DEF_INDEX {
881                            kw::Crate
882                        } else {
883                            def_key
884                                .disambiguated_data
885                                .data
886                                .get_opt_name()
887                                .unwrap_or_else(|| Symbol::intern("???"))
888                        };
889                        let visibility =
890                            root.tables.visibility.get(blob, item).unwrap().decode(blob).map_id(
891                                |index| {
892                                    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("crate{0}",
                DefPath::make(LOCAL_CRATE, index,
                        |parent|
                            root.tables.def_keys.get(blob,
                                        parent).unwrap().decode(blob)).to_string_no_crate_verbose()))
    })format!(
893                                        "crate{}",
894                                        DefPath::make(LOCAL_CRATE, index, |parent| root
895                                            .tables
896                                            .def_keys
897                                            .get(blob, parent)
898                                            .unwrap()
899                                            .decode(blob))
900                                        .to_string_no_crate_verbose()
901                                    )
902                                },
903                            );
904                        out.write_fmt(format_args!("{3: <4$}{0:?} {1:?} {2} {{", visibility, def_kind,
        def_name, "", indent))write!(
905                            out,
906                            "{nil: <indent$}{:?} {:?} {} {{",
907                            visibility,
908                            def_kind,
909                            def_name,
910                            nil = "",
911                        )?;
912
913                        if let Some(children) =
914                            root.tables.module_children_non_reexports.get(blob, item)
915                        {
916                            out.write_fmt(format_args!("\n"))write!(out, "\n")?;
917                            for child in children.decode(blob) {
918                                print_item(blob, out, child, indent + 4)?;
919                            }
920                            out.write_fmt(format_args!("{0: <1$}}}\n", "", indent))writeln!(out, "{nil: <indent$}}}", nil = "")?;
921                        } else {
922                            out.write_fmt(format_args!("}}\n"))writeln!(out, "}}")?;
923                        }
924
925                        Ok(())
926                    }
927
928                    print_item(self, out, CRATE_DEF_INDEX, 0)?;
929
930                    out.write_fmt(format_args!("\n"))write!(out, "\n")?;
931                }
932                "target_modifiers" => {
933                    out.write_fmt(format_args!("=Target modifiers=\n"))writeln!(out, "=Target modifiers=")?;
934
935                    for modifier in root.decode_target_modifiers(self) {
936                        let extended = modifier.extend();
937
938                        out.write_fmt(format_args!("-{0}{1}={2} [{3}]\n", extended.prefix,
        extended.name, modifier.value_name, extended.tech_value))writeln!(
939                            out,
940                            "-{}{}={} [{}]",
941                            extended.prefix,
942                            extended.name,
943                            modifier.value_name,
944                            extended.tech_value,
945                        )?;
946                    }
947                }
948
949                _ => {
950                    out.write_fmt(format_args!("unknown -Zls kind. allowed values are: all, root, lang_items, features, items, target_modifiers\n"))writeln!(
951                        out,
952                        "unknown -Zls kind. allowed values are: all, root, lang_items, features, items, \
953                            target_modifiers"
954                    )?;
955                }
956            }
957        }
958
959        Ok(())
960    }
961
962    pub(crate) fn get_proc_macro_info(&self) -> Vec<ProcMacroKind> {
963        self.get_root()
964            .proc_macro_data
965            .unwrap()
966            .macros
967            .decode(self)
968            .map(|(_id, kind)| kind.decode(self))
969            .collect::<Vec<_>>()
970    }
971}
972
973impl CrateRoot {
974    pub(crate) fn is_proc_macro_crate(&self) -> bool {
975        self.proc_macro_data.is_some()
976    }
977
978    pub(crate) fn name(&self) -> Symbol {
979        self.header.name
980    }
981
982    pub(crate) fn stable_crate_id(&self) -> StableCrateId {
983        self.stable_crate_id
984    }
985
986    pub(crate) fn decode_crate_deps<'a>(
987        &self,
988        metadata: &'a MetadataBlob,
989    ) -> impl ExactSizeIterator<Item = CrateDep> {
990        self.crate_deps.decode(metadata)
991    }
992
993    pub(crate) fn decode_target_modifiers<'a>(
994        &self,
995        metadata: &'a MetadataBlob,
996    ) -> impl ExactSizeIterator<Item = TargetModifier> {
997        self.target_modifiers.decode(metadata)
998    }
999
1000    pub(crate) fn decode_denied_partial_mitigations<'a>(
1001        &self,
1002        metadata: &'a MetadataBlob,
1003    ) -> impl ExactSizeIterator<Item = DeniedPartialMitigation> {
1004        self.denied_partial_mitigations.decode(metadata)
1005    }
1006}
1007
1008impl CrateMetadata {
1009    fn missing(&self, descr: &str, id: DefIndex) -> ! {
1010        ::rustc_span::macros::bug_impl(None,
    format_args!("missing `{1}` for {0:?}", self.local_def_id(id), descr),
    Location::caller())bug!("missing `{descr}` for {:?}", self.local_def_id(id))
1011    }
1012
1013    fn raw_proc_macro(&self, tcx: TyCtxt<'_>, id: DefIndex) -> (ProcMacroClient, ProcMacroKind) {
1014        // DefIndex's in root.proc_macro_data have a one-to-one correspondence
1015        // with items in 'raw_proc_macros'.
1016        let (pos, (_id, kind)) = self
1017            .root
1018            .proc_macro_data
1019            .as_ref()
1020            .unwrap()
1021            .macros
1022            .decode((self, tcx))
1023            .enumerate()
1024            .find(|(_pos, (i, _))| *i == id)
1025            .unwrap();
1026        (self.raw_proc_macros.unwrap()[pos], kind.decode((self, tcx)))
1027    }
1028
1029    fn opt_item_name(&self, item_index: DefIndex) -> Option<Symbol> {
1030        let def_key = self.def_key(item_index);
1031        def_key.disambiguated_data.data.get_opt_name().or_else(|| {
1032            if def_key.disambiguated_data.data == DefPathData::Ctor {
1033                let parent_index = def_key.parent.expect("no parent for a constructor");
1034                self.def_key(parent_index).disambiguated_data.data.get_opt_name()
1035            } else {
1036                None
1037            }
1038        })
1039    }
1040
1041    fn item_name(&self, item_index: DefIndex) -> Symbol {
1042        self.opt_item_name(item_index).expect("no encoded ident for item")
1043    }
1044
1045    fn opt_item_ident(&self, tcx: TyCtxt<'_>, item_index: DefIndex) -> Option<Ident> {
1046        let name = self.opt_item_name(item_index)?;
1047        let span = self
1048            .root
1049            .tables
1050            .def_ident_span
1051            .get(self, item_index)
1052            .unwrap_or_else(|| self.missing("def_ident_span", item_index))
1053            .decode((self, tcx));
1054        Some(Ident::new(name, span))
1055    }
1056
1057    fn item_ident(&self, tcx: TyCtxt<'_>, item_index: DefIndex) -> Ident {
1058        self.opt_item_ident(tcx, item_index).expect("no encoded ident for item")
1059    }
1060
1061    #[inline]
1062    pub(super) fn map_encoded_cnum_to_current(&self, cnum: CrateNum) -> CrateNum {
1063        if cnum == LOCAL_CRATE { self.cnum } else { self.cnum_map[cnum] }
1064    }
1065
1066    fn def_kind(&self, item_id: DefIndex) -> DefKind {
1067        self.root
1068            .tables
1069            .def_kind
1070            .get(self, item_id)
1071            .unwrap_or_else(|| self.missing("def_kind", item_id))
1072    }
1073
1074    fn get_span(&self, tcx: TyCtxt<'_>, index: DefIndex) -> Span {
1075        self.root
1076            .tables
1077            .def_span
1078            .get(self, index)
1079            .unwrap_or_else(|| self.missing("def_span", index))
1080            .decode((self, tcx))
1081    }
1082
1083    fn load_proc_macro<'tcx>(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> SyntaxExtension {
1084        let (name, kind, helper_attrs) = match self.raw_proc_macro(tcx, id) {
1085            (client, ProcMacroKind::CustomDerive { trait_name, attributes }) => {
1086                let helper_attrs =
1087                    attributes.into_iter().map(|attr| Symbol::intern(&attr)).collect();
1088                (
1089                    trait_name,
1090                    SyntaxExtensionKind::Derive(Arc::new(DeriveProcMacro { client })),
1091                    helper_attrs,
1092                )
1093            }
1094            (client, ProcMacroKind::Attr { name }) => {
1095                (name, SyntaxExtensionKind::Attr(Arc::new(AttrProcMacro { client })), Vec::new())
1096            }
1097            (client, ProcMacroKind::Bang { name }) => {
1098                (name, SyntaxExtensionKind::Bang(Arc::new(BangProcMacro { client })), Vec::new())
1099            }
1100        };
1101
1102        let sess = tcx.sess;
1103        let attrs: Vec<_> = self.get_item_attrs(tcx, id).collect();
1104        SyntaxExtension::new(
1105            sess,
1106            kind,
1107            self.get_span(tcx, id),
1108            helper_attrs,
1109            self.root.edition,
1110            Symbol::intern(&name),
1111            &attrs,
1112            false,
1113        )
1114    }
1115
1116    fn get_variant(
1117        &self,
1118        tcx: TyCtxt<'_>,
1119        kind: DefKind,
1120        index: DefIndex,
1121        parent_did: DefId,
1122    ) -> (VariantIdx, ty::VariantDef) {
1123        let adt_kind = match kind {
1124            DefKind::Variant => ty::AdtKind::Enum,
1125            DefKind::Struct => ty::AdtKind::Struct,
1126            DefKind::Union => ty::AdtKind::Union,
1127            _ => ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
    Location::caller())bug!(),
1128        };
1129
1130        let data = self.root.tables.variant_data.get(self, index).unwrap().decode((self, tcx));
1131
1132        let variant_did =
1133            if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
1134        let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
1135
1136        (
1137            data.idx,
1138            ty::VariantDef::new(
1139                self.item_name(index),
1140                variant_did,
1141                ctor,
1142                data.discr,
1143                self.get_associated_item_or_field_def_ids(tcx, index)
1144                    .map(|did| ty::FieldDef {
1145                        did,
1146                        name: self.item_name(did.index),
1147                        vis: self.get_visibility(tcx, did.index),
1148                        mut_restriction: self.get_mut_restriction(tcx, did.index),
1149                        safety: self.get_safety(did.index),
1150                        value: self.get_default_field(tcx, did.index),
1151                    })
1152                    .collect(),
1153                parent_did,
1154                None,
1155                data.is_non_exhaustive,
1156            ),
1157        )
1158    }
1159
1160    fn get_adt_def<'tcx>(&self, tcx: TyCtxt<'tcx>, item_id: DefIndex) -> ty::AdtDef<'tcx> {
1161        let kind = self.def_kind(item_id);
1162        let did = self.local_def_id(item_id);
1163
1164        let adt_kind = match kind {
1165            DefKind::Enum => ty::AdtKind::Enum,
1166            DefKind::Struct => ty::AdtKind::Struct,
1167            DefKind::Union => ty::AdtKind::Union,
1168            _ => ::rustc_span::macros::bug_impl(None,
    format_args!("get_adt_def called on a non-ADT {0:?}", did),
    Location::caller())bug!("get_adt_def called on a non-ADT {:?}", did),
1169        };
1170        let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode((self, tcx));
1171
1172        let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind {
1173            self.root
1174                .tables
1175                .module_children_non_reexports
1176                .get(self, item_id)
1177                .expect("variants are not encoded for an enum")
1178                .decode((self, tcx))
1179                .filter_map(|index| {
1180                    let kind = self.def_kind(index);
1181                    match kind {
1182                        DefKind::Ctor(..) => None,
1183                        _ => Some(self.get_variant(tcx, kind, index, did)),
1184                    }
1185                })
1186                .collect()
1187        } else {
1188            std::iter::once(self.get_variant(tcx, kind, item_id, did)).collect()
1189        };
1190
1191        variants.sort_by_key(|(idx, _)| *idx);
1192
1193        tcx.mk_adt_def(
1194            did,
1195            adt_kind,
1196            variants.into_iter().map(|(_, variant)| variant).collect(),
1197            repr,
1198        )
1199    }
1200
1201    fn get_visibility(&self, tcx: TyCtxt<'_>, id: DefIndex) -> Visibility<ModId> {
1202        self.root
1203            .tables
1204            .visibility
1205            .get(self, id)
1206            .unwrap_or_else(|| self.missing("visibility", id))
1207            .decode((self, tcx))
1208            .map_id(|index| ModId::new_unchecked(self.local_def_id(index)))
1209    }
1210
1211    fn get_mut_restriction(&self, tcx: TyCtxt<'_>, id: DefIndex) -> RestrictionKind {
1212        self.root
1213            .tables
1214            .mut_restriction
1215            .get(self, id)
1216            .unwrap_or_else(|| self.missing("mut_restriction", id))
1217            .decode((self, tcx))
1218    }
1219
1220    fn get_safety(&self, id: DefIndex) -> Safety {
1221        self.root.tables.safety.get(self, id)
1222    }
1223
1224    fn get_default_field(&self, tcx: TyCtxt<'_>, id: DefIndex) -> Option<DefId> {
1225        self.root.tables.default_fields.get(self, id).map(|d| d.decode((self, tcx)))
1226    }
1227
1228    fn get_expn_that_defined(&self, tcx: TyCtxt<'_>, id: DefIndex) -> ExpnId {
1229        self.root
1230            .tables
1231            .expn_that_defined
1232            .get(self, id)
1233            .unwrap_or_else(|| self.missing("expn_that_defined", id))
1234            .decode((self, tcx))
1235    }
1236
1237    fn get_debugger_visualizers(&self, tcx: TyCtxt<'_>) -> Vec<DebuggerVisualizerFile> {
1238        self.root.debugger_visualizers.decode((self, tcx)).collect::<Vec<_>>()
1239    }
1240
1241    /// Iterates over all the stability attributes in the given crate.
1242    fn get_lib_features(&self, tcx: TyCtxt<'_>) -> LibFeatures {
1243        LibFeatures {
1244            stability: self
1245                .root
1246                .lib_features
1247                .decode((self, tcx))
1248                .map(|(sym, stab)| (sym, (stab, DUMMY_SP)))
1249                .collect(),
1250        }
1251    }
1252
1253    /// Iterates over the stability implications in the given crate (when a `#[unstable]` attribute
1254    /// has an `implied_by` meta item, then the mapping from the implied feature to the actual
1255    /// feature is a stability implication).
1256    fn get_stability_implications<'tcx>(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(Symbol, Symbol)] {
1257        tcx.arena.alloc_from_iter(self.root.stability_implications.decode((self, tcx)))
1258    }
1259
1260    /// Iterates over the lang items in the given crate.
1261    fn get_lang_items<'tcx>(&self, tcx: TyCtxt<'tcx>) -> &'tcx [(DefId, LangItem)] {
1262        tcx.arena.alloc_from_iter(
1263            self.root
1264                .lang_items
1265                .decode((self, tcx))
1266                .map(move |(def_index, index)| (self.local_def_id(def_index), index)),
1267        )
1268    }
1269
1270    fn get_stripped_cfg_items<'tcx>(
1271        &self,
1272        tcx: TyCtxt<'tcx>,
1273        cnum: CrateNum,
1274    ) -> &'tcx [StrippedCfgItem] {
1275        let item_names = self
1276            .root
1277            .stripped_cfg_items
1278            .decode((self, tcx))
1279            .map(|item| item.map_scope_id(|index| DefId { krate: cnum, index }));
1280        tcx.arena.alloc_from_iter(item_names)
1281    }
1282
1283    /// Iterates over the diagnostic items in the given crate.
1284    fn get_diagnostic_items(&self, tcx: TyCtxt<'_>) -> DiagnosticItems {
1285        let mut id_to_name = DefIdMap::default();
1286        let name_to_id = self
1287            .root
1288            .diagnostic_items
1289            .decode((self, tcx))
1290            .map(|(name, def_index)| {
1291                let id = self.local_def_id(def_index);
1292                id_to_name.insert(id, name);
1293                (name, id)
1294            })
1295            .collect();
1296        DiagnosticItems { id_to_name, name_to_id }
1297    }
1298
1299    /// Iterates over the canonical_symbols in the given crate.
1300    fn get_canonical_symbols(&self, tcx: TyCtxt<'_>) -> CanonicalSymbols {
1301        let mut canonical_symbols = CanonicalSymbols::new();
1302
1303        for (name, def_index) in self.root.canonical_symbols.decode((self, tcx)) {
1304            let id = self.local_def_id(def_index);
1305            let _ = canonical_symbols.set(name, id);
1306        }
1307
1308        canonical_symbols
1309    }
1310
1311    /// Iterates over the fake_doc_items in the given crate.
1312    fn get_fake_doc_items(&self, tcx: TyCtxt<'_>) -> Vec<DefId> {
1313        let mut fake_doc_items = Vec::new();
1314
1315        for def_index in self.root.fake_doc_items.decode((self, tcx)) {
1316            let id = self.local_def_id(def_index);
1317            fake_doc_items.push(id);
1318        }
1319
1320        fake_doc_items
1321    }
1322
1323    fn get_mod_child(&self, tcx: TyCtxt<'_>, id: DefIndex) -> ModChild {
1324        let ident = self.item_ident(tcx, id);
1325        let res = Res::Def(self.def_kind(id), self.local_def_id(id));
1326        let vis = self.get_visibility(tcx, id);
1327
1328        ModChild { ident, res, vis, reexport_chain: Default::default() }
1329    }
1330
1331    /// Iterates over all named children of the given module,
1332    /// including both proper items and reexports.
1333    /// Module here is understood in name resolution sense - it can be a `mod` item,
1334    /// or a crate root, or an enum, or a trait.
1335    ///
1336    /// # Panics
1337    ///
1338    /// May panic if the provided `id` does not refer to a module.
1339    fn get_module_children(&self, tcx: TyCtxt<'_>, id: DefIndex) -> impl Iterator<Item = ModChild> {
1340        gen move {
1341            if let Some(data) = &self.root.proc_macro_data {
1342                // If we are loading as a proc macro, we want to return
1343                // the view of this crate as a proc macro crate.
1344                if id == CRATE_DEF_INDEX {
1345                    for (child_index, _) in data.macros.decode((self, tcx)) {
1346                        yield self.get_mod_child(tcx, child_index);
1347                    }
1348                }
1349            } else {
1350                // Iterate over all children.
1351                let non_reexports = self.root.tables.module_children_non_reexports.get(self, id);
1352                let non_reexports =
1353                    non_reexports.expect("provided `DefIndex` must refer to a module-like item");
1354                for child_index in non_reexports.decode((self, tcx)) {
1355                    yield self.get_mod_child(tcx, child_index);
1356                }
1357
1358                let reexports = self.root.tables.module_children_reexports.get(self, id);
1359                if !reexports.is_default() {
1360                    for reexport in reexports.decode((self, tcx)) {
1361                        yield reexport;
1362                    }
1363                }
1364            }
1365        }
1366    }
1367
1368    fn get_ambig_module_children(
1369        &self,
1370        tcx: TyCtxt<'_>,
1371        id: DefIndex,
1372    ) -> impl Iterator<Item = AmbigModChild> {
1373        gen move {
1374            let children = self.root.tables.ambig_module_children.get(self, id);
1375            if !children.is_default() {
1376                for child in children.decode((self, tcx)) {
1377                    yield child;
1378                }
1379            }
1380        }
1381    }
1382
1383    fn is_item_mir_available(&self, id: DefIndex) -> bool {
1384        self.root.tables.optimized_mir.get(self, id).is_some()
1385    }
1386
1387    fn get_fn_has_self_parameter(&self, tcx: TyCtxt<'_>, id: DefIndex) -> bool {
1388        self.root
1389            .tables
1390            .fn_arg_idents
1391            .get(self, id)
1392            .expect("argument names not encoded for a function")
1393            .decode((self, tcx))
1394            .nth(0)
1395            .is_some_and(|ident| #[allow(non_exhaustive_omitted_patterns)] match ident {
    Some(Ident { name: kw::SelfLower, .. }) => true,
    _ => false,
}matches!(ident, Some(Ident { name: kw::SelfLower, .. })))
1396    }
1397
1398    fn get_associated_item_or_field_def_ids(
1399        &self,
1400        tcx: TyCtxt<'_>,
1401        id: DefIndex,
1402    ) -> impl Iterator<Item = DefId> {
1403        self.root
1404            .tables
1405            .associated_item_or_field_def_ids
1406            .get(self, id)
1407            .unwrap_or_else(|| self.missing("associated_item_or_field_def_ids", id))
1408            .decode((self, tcx))
1409            .map(move |child_index| self.local_def_id(child_index))
1410    }
1411
1412    fn get_associated_item(&self, tcx: TyCtxt<'_>, id: DefIndex) -> ty::AssocItem {
1413        let kind = match self.def_kind(id) {
1414            DefKind::AssocConst => ty::AssocKind::Const { name: self.item_name(id) },
1415            DefKind::AssocFn => ty::AssocKind::Fn {
1416                name: self.item_name(id),
1417                has_self: self.get_fn_has_self_parameter(tcx, id),
1418            },
1419            DefKind::AssocTy => {
1420                let data = if let Some(rpitit_info) = self.root.tables.opt_rpitit_info.get(self, id)
1421                {
1422                    ty::AssocTypeData::Rpitit(rpitit_info.decode((self, tcx)))
1423                } else {
1424                    ty::AssocTypeData::Normal(self.item_name(id))
1425                };
1426                ty::AssocKind::Type { data }
1427            }
1428            _ => ::rustc_span::macros::bug_impl(None,
    format_args!("cannot get associated-item of `{0:?}`", self.def_key(id)),
    Location::caller())bug!("cannot get associated-item of `{:?}`", self.def_key(id)),
1429        };
1430        let container = self.root.tables.assoc_container.get(self, id).unwrap().decode((self, tcx));
1431
1432        ty::AssocItem { kind, def_id: self.local_def_id(id), container }
1433    }
1434
1435    fn get_ctor(&self, tcx: TyCtxt<'_>, node_id: DefIndex) -> Option<(CtorKind, DefId)> {
1436        match self.def_kind(node_id) {
1437            DefKind::Struct | DefKind::Variant => {
1438                let vdata =
1439                    self.root.tables.variant_data.get(self, node_id).unwrap().decode((self, tcx));
1440                vdata.ctor.map(|(kind, index)| (kind, self.local_def_id(index)))
1441            }
1442            _ => None,
1443        }
1444    }
1445
1446    fn get_item_attrs(
1447        &self,
1448        tcx: TyCtxt<'_>,
1449        id: DefIndex,
1450    ) -> impl Iterator<Item = rustc_attr_ir::Attribute> {
1451        self.root
1452            .tables
1453            .attributes
1454            .get(self, id)
1455            .unwrap_or_else(|| {
1456                let def_key = self.def_key(id);
1457                match def_key.disambiguated_data.data {
1458                    DefPathData::Ctor => {
1459                        // Structure and variant constructors don't have any attributes encoded for them,
1460                        // but we assume that someone passing a constructor ID actually wants to look at
1461                        // the attributes on the corresponding struct or variant.
1462                        let parent_id = def_key.parent.expect("no parent for a constructor");
1463                        self.root
1464                            .tables
1465                            .attributes
1466                            .get(self, parent_id)
1467                            .expect("no encoded attributes for a structure or variant")
1468                    }
1469                    DefPathData::SyntheticCoroutineBody => {
1470                        // SyntheticCoroutineBodies cannot have attributes
1471                        LazyArray::default()
1472                    }
1473                    _ => {
    ::core::panicking::panic_fmt(format_args!("Definition key {1:?} of type `{0:?}` did not have any attributes stored",
            def_key.disambiguated_data.data, def_key));
}panic!("Definition key {def_key:?} of type `{:?}` did not have any attributes stored", def_key.disambiguated_data.data)
1474                }
1475            })
1476            .decode((self, tcx))
1477    }
1478
1479    fn get_inherent_implementations_for_type<'tcx>(
1480        &self,
1481        tcx: TyCtxt<'tcx>,
1482        id: DefIndex,
1483    ) -> &'tcx [DefId] {
1484        tcx.arena.alloc_from_iter(
1485            self.root
1486                .tables
1487                .inherent_impls
1488                .get(self, id)
1489                .decode((self, tcx))
1490                .map(|index| self.local_def_id(index)),
1491        )
1492    }
1493
1494    /// Decodes all traits in the crate (for rustdoc and rustc diagnostics).
1495    fn get_traits(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> {
1496        self.root.traits.decode((self, tcx)).map(move |index| self.local_def_id(index))
1497    }
1498
1499    /// Decodes all trait impls in the crate (for rustdoc).
1500    fn get_trait_impls(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> {
1501        self.trait_impls.values().flat_map(move |impls| {
1502            impls.decode((self, tcx)).map(move |(impl_index, _)| self.local_def_id(impl_index))
1503        })
1504    }
1505
1506    fn get_incoherent_impls<'tcx>(&self, tcx: TyCtxt<'tcx>, simp: SimplifiedType) -> &'tcx [DefId] {
1507        if let Some(impls) = self.incoherent_impls.get(&simp) {
1508            tcx.arena.alloc_from_iter(impls.decode((self, tcx)).map(|idx| self.local_def_id(idx)))
1509        } else {
1510            &[]
1511        }
1512    }
1513
1514    fn get_implementations_of_trait<'tcx>(
1515        &self,
1516        tcx: TyCtxt<'tcx>,
1517        trait_def_id: DefId,
1518    ) -> &'tcx [(DefId, Option<SimplifiedType>)] {
1519        if self.trait_impls.is_empty() {
1520            return &[];
1521        }
1522
1523        // Do a reverse lookup beforehand to avoid touching the crate_num
1524        // hash map in the loop below.
1525        let key = match self.reverse_translate_def_id(trait_def_id) {
1526            Some(def_id) => (def_id.krate.as_u32(), def_id.index),
1527            None => return &[],
1528        };
1529
1530        if let Some(impls) = self.trait_impls.get(&key) {
1531            tcx.arena.alloc_from_iter(
1532                impls
1533                    .decode((self, tcx))
1534                    .map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty)),
1535            )
1536        } else {
1537            &[]
1538        }
1539    }
1540
1541    fn get_native_libraries(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = NativeLib> {
1542        self.root.native_libraries.decode((self, tcx))
1543    }
1544
1545    fn get_proc_macro_quoted_span(&self, tcx: TyCtxt<'_>, index: usize) -> Span {
1546        self.root
1547            .tables
1548            .proc_macro_quoted_spans
1549            .get(self, index)
1550            .unwrap_or_else(|| {
    ::core::panicking::panic_fmt(format_args!("Missing proc macro quoted span: {0:?}",
            index));
}panic!("Missing proc macro quoted span: {index:?}"))
1551            .decode((self, tcx))
1552    }
1553
1554    fn get_foreign_modules(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = ForeignModule> {
1555        self.root.foreign_modules.decode((self, tcx))
1556    }
1557
1558    fn get_dylib_dependency_formats<'tcx>(
1559        &self,
1560        tcx: TyCtxt<'tcx>,
1561    ) -> &'tcx [(CrateNum, LinkagePreference)] {
1562        tcx.arena.alloc_from_iter(
1563            self.root.dylib_dependency_formats.decode((self, tcx)).enumerate().flat_map(
1564                |(i, link)| {
1565                    let cnum = CrateNum::new(i + 1); // We skipped LOCAL_CRATE when encoding
1566                    link.map(|link| (self.cnum_map[cnum], link))
1567                },
1568            ),
1569        )
1570    }
1571
1572    fn get_externally_implementable_items(
1573        &self,
1574        tcx: TyCtxt<'_>,
1575    ) -> impl Iterator<Item = EiiMapEncodedKeyValue> {
1576        self.root.externally_implementable_items.decode((self, tcx))
1577    }
1578
1579    fn get_missing_lang_items<'tcx>(&self, tcx: TyCtxt<'tcx>) -> &'tcx [LangItem] {
1580        tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode((self, tcx)))
1581    }
1582
1583    fn get_exportable_items(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> {
1584        self.root.exportable_items.decode((self, tcx)).map(move |index| self.local_def_id(index))
1585    }
1586
1587    fn get_stable_order_of_exportable_impls(
1588        &self,
1589        tcx: TyCtxt<'_>,
1590    ) -> impl Iterator<Item = (DefId, usize)> {
1591        self.root
1592            .stable_order_of_exportable_impls
1593            .decode((self, tcx))
1594            .map(move |v| (self.local_def_id(v.0), v.1))
1595    }
1596
1597    fn exported_non_generic_symbols<'tcx>(
1598        &self,
1599        tcx: TyCtxt<'tcx>,
1600    ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
1601        tcx.arena.alloc_from_iter(self.root.exported_non_generic_symbols.decode((self, tcx)))
1602    }
1603
1604    fn exported_generic_symbols<'tcx>(
1605        &self,
1606        tcx: TyCtxt<'tcx>,
1607    ) -> &'tcx [(ExportedSymbol<'tcx>, SymbolExportInfo)] {
1608        tcx.arena.alloc_from_iter(self.root.exported_generic_symbols.decode((self, tcx)))
1609    }
1610
1611    fn get_macro(&self, tcx: TyCtxt<'_>, id: DefIndex) -> ast::MacroDef {
1612        match self.def_kind(id) {
1613            DefKind::Macro(_) => {
1614                let macro_rules = self.root.tables.is_macro_rules.get(self, id);
1615                let body =
1616                    self.root.tables.macro_definition.get(self, id).unwrap().decode((self, tcx));
1617                ast::MacroDef { macro_rules, body: Box::new(body), eii_declaration: None }
1618            }
1619            _ => ::rustc_span::macros::bug_impl(None, format_args!("impossible case reached"),
    Location::caller())bug!(),
1620        }
1621    }
1622
1623    #[inline]
1624    fn def_key(&self, index: DefIndex) -> DefKey {
1625        *self.def_key_cache.lock().entry(index).or_insert_with(|| {
1626            self.root.tables.def_keys.get(&self.blob, index).unwrap().decode(&self.blob)
1627        })
1628    }
1629
1630    // Returns the path leading to the thing with this `id`.
1631    fn def_path(&self, id: DefIndex) -> DefPath {
1632        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs:1632",
                        "rustc_metadata::rmeta::decoder", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs"),
                        ::tracing_core::__macro_support::Option::Some(1632u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_metadata::rmeta::decoder"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("def_path(cnum={0:?}, id={1:?})",
                                                    self.cnum, id) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!("def_path(cnum={:?}, id={:?})", self.cnum, id);
1633        DefPath::make(self.cnum, id, |parent| self.def_key(parent))
1634    }
1635
1636    #[inline]
1637    fn def_path_hash(&self, index: DefIndex) -> DefPathHash {
1638        // This is a hack to workaround the fact that we can't easily encode/decode a Hash64
1639        // into the FixedSizeEncoding, as Hash64 lacks a Default impl. A future refactor to
1640        // relax the Default restriction will likely fix this.
1641        let fingerprint = Fingerprint::new(
1642            self.root.stable_crate_id.as_u64(),
1643            self.root.tables.def_path_hashes.get(&self.blob, index),
1644        );
1645        DefPathHash::new(self.root.stable_crate_id, fingerprint.split().1)
1646    }
1647
1648    #[inline]
1649    fn def_path_hash_to_def_index(&self, hash: DefPathHash) -> Option<DefIndex> {
1650        self.def_path_hash_map.def_path_hash_to_def_index(&hash)
1651    }
1652
1653    fn expn_hash_to_expn_id(&self, tcx: TyCtxt<'_>, index_guess: u32, hash: ExpnHash) -> ExpnId {
1654        let index_guess = ExpnIndex::from_u32(index_guess);
1655        let old_hash =
1656            self.root.expn_hashes.get(self, index_guess).map(|lazy| lazy.decode((self, tcx)));
1657
1658        let index = if old_hash == Some(hash) {
1659            // Fast path: the expn and its index is unchanged from the
1660            // previous compilation session. There is no need to decode anything
1661            // else.
1662            index_guess
1663        } else {
1664            // Slow path: We need to find out the new `DefIndex` of the provided
1665            // `DefPathHash`, if its still exists. This requires decoding every `DefPathHash`
1666            // stored in this crate.
1667            let map = self.expn_hash_map.get_or_init(|| {
1668                let end_id = self.root.expn_hashes.size() as u32;
1669                let mut map =
1670                    UnhashMap::with_capacity_and_hasher(end_id as usize, Default::default());
1671                for i in 0..end_id {
1672                    let i = ExpnIndex::from_u32(i);
1673                    if let Some(hash) = self.root.expn_hashes.get(self, i) {
1674                        map.insert(hash.decode((self, tcx)), i);
1675                    }
1676                }
1677                map
1678            });
1679            map[&hash]
1680        };
1681
1682        let data = self.root.expn_data.get(self, index).unwrap().decode((self, tcx));
1683        rustc_span::hygiene::register_expn_id(self.cnum, index, data, hash)
1684    }
1685
1686    /// Imports the source_map from an external crate into the source_map of the crate
1687    /// currently being compiled (the "local crate").
1688    ///
1689    /// The import algorithm works analogous to how AST items are inlined from an
1690    /// external crate's metadata:
1691    /// For every SourceFile in the external source_map an 'inline' copy is created in the
1692    /// local source_map. The correspondence relation between external and local
1693    /// SourceFiles is recorded in the `ImportedSourceFile` objects returned from this
1694    /// function. When an item from an external crate is later inlined into this
1695    /// crate, this correspondence information is used to translate the span
1696    /// information of the inlined item so that it refers the correct positions in
1697    /// the local source_map (see `<decoder::DecodeContext as SpecializedDecoder<Span>>`).
1698    ///
1699    /// The import algorithm in the function below will reuse SourceFiles already
1700    /// existing in the local source_map. For example, even if the SourceFile of some
1701    /// source file of libstd gets imported many times, there will only ever be
1702    /// one SourceFile object for the corresponding file in the local source_map.
1703    ///
1704    /// Note that imported SourceFiles do not actually contain the source code of the
1705    /// file they represent, just information about length, line breaks, and
1706    /// multibyte characters. This information is enough to generate valid debuginfo
1707    /// for items inlined from other crates.
1708    ///
1709    /// Proc macro crates don't currently export spans, so this function does not have
1710    /// to work for them.
1711    fn imported_source_file(&self, tcx: TyCtxt<'_>, source_file_index: u32) -> ImportedSourceFile {
1712        fn filter<'a>(
1713            tcx: TyCtxt<'_>,
1714            real_source_base_dir: &Option<PathBuf>,
1715            path: Option<&'a Path>,
1716        ) -> Option<&'a Path> {
1717            path.filter(|_| {
1718                // Only spend time on further checks if we have what to translate *to*.
1719                real_source_base_dir.is_some()
1720                // Some tests need the translation to be always skipped.
1721                && tcx.sess.opts.unstable_opts.translate_remapped_path_to_local_path
1722            })
1723            .filter(|virtual_dir| {
1724                // Don't translate away `/rustc/$hash` if we're still remapping to it,
1725                // since that means we're still building `std`/`rustc` that need it,
1726                // and we don't want the real path to leak into codegen/debuginfo.
1727                !tcx.sess.opts.remap_path_prefix.iter().any(|(_from, to)| to == virtual_dir)
1728            })
1729        }
1730
1731        let try_to_translate_virtual_to_real =
1732            |virtual_source_base_dir: Option<&str>,
1733             real_source_base_dir: &Option<PathBuf>,
1734             name: &mut rustc_span::FileName| {
1735                let virtual_source_base_dir = [
1736                    filter(tcx, real_source_base_dir, virtual_source_base_dir.map(Path::new)),
1737                    filter(
1738                        tcx,
1739                        real_source_base_dir,
1740                        tcx.sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref(),
1741                    ),
1742                ];
1743
1744                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs:1744",
                        "rustc_metadata::rmeta::decoder", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs"),
                        ::tracing_core::__macro_support::Option::Some(1744u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_metadata::rmeta::decoder"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("try_to_translate_virtual_to_real(name={0:?}): virtual_source_base_dir={1:?}, real_source_base_dir={2:?}",
                                                    name, virtual_source_base_dir, real_source_base_dir) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
1745                    "try_to_translate_virtual_to_real(name={:?}): \
1746                     virtual_source_base_dir={:?}, real_source_base_dir={:?}",
1747                    name, virtual_source_base_dir, real_source_base_dir,
1748                );
1749
1750                for virtual_dir in virtual_source_base_dir.iter().flatten() {
1751                    if let Some(real_dir) = &real_source_base_dir
1752                        && let rustc_span::FileName::Real(old_name) = name
1753                        && let virtual_path = old_name.path(RemapPathScopeComponents::MACRO)
1754                        && let Ok(rest) = virtual_path.strip_prefix(virtual_dir)
1755                    {
1756                        let new_path = real_dir.join(rest);
1757
1758                        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs:1758",
                        "rustc_metadata::rmeta::decoder", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs"),
                        ::tracing_core::__macro_support::Option::Some(1758u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_metadata::rmeta::decoder"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("try_to_translate_virtual_to_real: `{0}` -> `{1}`",
                                                    virtual_path.display(), new_path.display()) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
1759                            "try_to_translate_virtual_to_real: `{}` -> `{}`",
1760                            virtual_path.display(),
1761                            new_path.display(),
1762                        );
1763
1764                        // Check if the translated real path is affected by any user-requested
1765                        // remaps via --remap-path-prefix. Apply them if so.
1766                        // Note that this is a special case for imported rust-src paths specified by
1767                        // https://rust-lang.github.io/rfcs/3127-trim-paths.html#handling-sysroot-paths.
1768                        // Other imported paths are not currently remapped (see #66251).
1769                        *name = rustc_span::FileName::Real(
1770                            tcx.sess
1771                                .source_map()
1772                                .path_mapping()
1773                                .to_real_filename(&rustc_span::RealFileName::empty(), new_path),
1774                        );
1775                    }
1776                }
1777            };
1778
1779        let try_to_translate_real_to_virtual =
1780            |virtual_source_base_dir: Option<&str>,
1781             real_source_base_dir: &Option<PathBuf>,
1782             subdir: &str,
1783             name: &mut rustc_span::FileName| {
1784                if let Some(virtual_dir) =
1785                    &tcx.sess.opts.unstable_opts.simulate_remapped_rust_src_base
1786                    && let Some(real_dir) = real_source_base_dir
1787                    && let rustc_span::FileName::Real(old_name) = name
1788                {
1789                    let (_working_dir, embeddable_path) =
1790                        old_name.embeddable_name(RemapPathScopeComponents::MACRO);
1791                    let relative_path = embeddable_path.strip_prefix(real_dir).ok().or_else(|| {
1792                        virtual_source_base_dir
1793                            .and_then(|virtual_dir| embeddable_path.strip_prefix(virtual_dir).ok())
1794                    });
1795                    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs:1795",
                        "rustc_metadata::rmeta::decoder", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs"),
                        ::tracing_core::__macro_support::Option::Some(1795u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_metadata::rmeta::decoder"),
                        ::tracing_core::field::FieldSet::new(&["message",
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("relative_path")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("relative_path");
                                            NAME.as_str()
                                        },
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("virtual_dir")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("virtual_dir");
                                            NAME.as_str()
                                        },
                                        {
                                            const NAME:
                                                ::tracing::__macro_support::FieldName<{
                                                    ::tracing::__macro_support::FieldName::len("subdir")
                                                }> =
                                                ::tracing::__macro_support::FieldName::new("subdir");
                                            NAME.as_str()
                                        }], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("simulate_remapped_rust_src_base")
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&relative_path)
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&virtual_dir)
                                            as &dyn ::tracing::field::Value)),
                                (::tracing::__macro_support::Option::Some(&::tracing::field::debug(&subdir)
                                            as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
1796                        ?relative_path,
1797                        ?virtual_dir,
1798                        ?subdir,
1799                        "simulate_remapped_rust_src_base"
1800                    );
1801                    if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok()) {
1802                        *name =
1803                            rustc_span::FileName::Real(rustc_span::RealFileName::from_virtual_path(
1804                                &virtual_dir.join(subdir).join(rest),
1805                            ))
1806                    }
1807                }
1808            };
1809
1810        let mut import_info = self.source_map_import_info.lock();
1811        for _ in import_info.len()..=(source_file_index as usize) {
1812            import_info.push(None);
1813        }
1814        import_info[source_file_index as usize]
1815            .get_or_insert_with(|| {
1816                let source_file_to_import = self
1817                    .root
1818                    .source_map
1819                    .get(self, source_file_index)
1820                    .expect("missing source file")
1821                    .decode((self, tcx));
1822
1823                // We can't reuse an existing SourceFile, so allocate a new one
1824                // containing the information we need.
1825                let original_end_pos = source_file_to_import.end_position();
1826                let rustc_span::SourceFile {
1827                    mut name,
1828                    src_hash,
1829                    checksum_hash,
1830                    start_pos: original_start_pos,
1831                    normalized_source_len,
1832                    unnormalized_source_len,
1833                    lines,
1834                    multibyte_chars,
1835                    normalized_pos,
1836                    stable_id,
1837                    ..
1838                } = source_file_to_import;
1839
1840                // If this file is under $sysroot/lib/rustlib/src/
1841                // and the user wish to simulate remapping with -Z simulate-remapped-rust-src-base,
1842                // then we change `name` to a similar state as if the rust was bootstrapped
1843                // with `remap-debuginfo = true`.
1844                // This is useful for testing so that tests about the effects of
1845                // `try_to_translate_virtual_to_real` don't have to worry about how the
1846                // compiler is bootstrapped.
1847                try_to_translate_real_to_virtual(
1848                    ::core::option::Option::Some("/rustc/d080e7dff1b0fc54541545252818f8cccf995d05")option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"),
1849                    &tcx.sess.opts.real_rust_source_base_dir,
1850                    "library",
1851                    &mut name,
1852                );
1853
1854                // If this file is under $sysroot/lib/rustlib/rustc-src/
1855                // and the user wish to simulate remapping with -Z simulate-remapped-rust-src-base,
1856                // then we change `name` to a similar state as if the rust was bootstrapped
1857                // with `remap-debuginfo = true`.
1858                try_to_translate_real_to_virtual(
1859                    ::core::option::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05")option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"),
1860                    &tcx.sess.opts.real_rustc_dev_source_base_dir,
1861                    "compiler",
1862                    &mut name,
1863                );
1864
1865                // If this file's path has been remapped to `/rustc/$hash`,
1866                // we might be able to reverse that.
1867                //
1868                // NOTE: if you update this, you might need to also update bootstrap's code for generating
1869                // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
1870                try_to_translate_virtual_to_real(
1871                    ::core::option::Option::Some("/rustc/d080e7dff1b0fc54541545252818f8cccf995d05")option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"),
1872                    &tcx.sess.opts.real_rust_source_base_dir,
1873                    &mut name,
1874                );
1875
1876                // If this file's path has been remapped to `/rustc-dev/$hash`,
1877                // we might be able to reverse that.
1878                //
1879                // NOTE: if you update this, you might need to also update bootstrap's code for generating
1880                // the `rustc-dev` component in `Src::run` in `src/bootstrap/dist.rs`.
1881                try_to_translate_virtual_to_real(
1882                    ::core::option::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05")option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"),
1883                    &tcx.sess.opts.real_rustc_dev_source_base_dir,
1884                    &mut name,
1885                );
1886
1887                let local_version = tcx.sess.source_map().new_imported_source_file(
1888                    name,
1889                    src_hash,
1890                    checksum_hash,
1891                    stable_id,
1892                    normalized_source_len.to_u32(),
1893                    unnormalized_source_len,
1894                    self.cnum,
1895                    lines,
1896                    multibyte_chars,
1897                    normalized_pos,
1898                    source_file_index,
1899                );
1900                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs:1900",
                        "rustc_metadata::rmeta::decoder", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/d080e7dff1b0fc54541545252818f8cccf995d05/compiler/rustc_metadata/src/rmeta/decoder.rs"),
                        ::tracing_core::__macro_support::Option::Some(1900u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_metadata::rmeta::decoder"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("CrateMetaData::imported_source_files alloc source_file {0:?} original (start_pos {1:?} source_len {2:?}) translated (start_pos {3:?} source_len {4:?})",
                                                    local_version.name, original_start_pos,
                                                    normalized_source_len, local_version.start_pos,
                                                    local_version.normalized_source_len) as
                                            &dyn ::tracing::field::Value))])
            });
    } else { ; }
};debug!(
1901                    "CrateMetaData::imported_source_files alloc \
1902                         source_file {:?} original (start_pos {:?} source_len {:?}) \
1903                         translated (start_pos {:?} source_len {:?})",
1904                    local_version.name,
1905                    original_start_pos,
1906                    normalized_source_len,
1907                    local_version.start_pos,
1908                    local_version.normalized_source_len
1909                );
1910
1911                ImportedSourceFile {
1912                    original_start_pos,
1913                    original_end_pos,
1914                    translated_source_file: local_version,
1915                }
1916            })
1917            .clone()
1918    }
1919
1920    fn get_attr_flags(&self, index: DefIndex) -> AttrFlags {
1921        self.root.tables.attr_flags.get(self, index)
1922    }
1923
1924    fn get_intrinsic(&self, tcx: TyCtxt<'_>, index: DefIndex) -> Option<ty::IntrinsicDef> {
1925        self.root.tables.intrinsic.get(self, index).map(|d| d.decode((self, tcx)))
1926    }
1927
1928    fn get_doc_link_resolutions(&self, tcx: TyCtxt<'_>, index: DefIndex) -> DocLinkResMap {
1929        self.root
1930            .tables
1931            .doc_link_resolutions
1932            .get(self, index)
1933            .expect("no resolutions for a doc link")
1934            .decode((self, tcx))
1935    }
1936
1937    fn get_doc_link_traits_in_scope(
1938        &self,
1939        tcx: TyCtxt<'_>,
1940        index: DefIndex,
1941    ) -> impl Iterator<Item = DefId> {
1942        self.root
1943            .tables
1944            .doc_link_traits_in_scope
1945            .get(self, index)
1946            .expect("no traits in scope for a doc link")
1947            .decode((self, tcx))
1948    }
1949}
1950
1951impl CrateMetadata {
1952    pub(crate) fn new(
1953        tcx: TyCtxt<'_>,
1954        blob: MetadataBlob,
1955        root: CrateRoot,
1956        unhashed: CrateRootUnhashed,
1957        raw_proc_macros: Option<&'static [ProcMacroClient]>,
1958        cnum: CrateNum,
1959        cnum_map: CrateNumMap,
1960        dep_kind: CrateDepKind,
1961        source: CrateSource,
1962        private_dep: bool,
1963        host_hash: Option<Svh>,
1964    ) -> CrateMetadata {
1965        let trait_impls = root
1966            .impls
1967            .decode(&blob)
1968            .map(|trait_impls| (trait_impls.trait_id, trait_impls.impls))
1969            .collect();
1970        let alloc_decoding_state =
1971            AllocDecodingState::new(root.interpret_alloc_index.decode(&blob).collect());
1972
1973        // Pre-decode the DefPathHash->DefIndex table. This is a cheap operation
1974        // that does not copy any data. It just does some data verification.
1975        let def_path_hash_map = root.def_path_hash_map.decode(&blob);
1976
1977        let mut cdata = CrateMetadata {
1978            blob,
1979            root,
1980            unhashed,
1981            trait_impls,
1982            incoherent_impls: Default::default(),
1983            raw_proc_macros,
1984            source_map_import_info: Lock::new(Vec::new()),
1985            def_path_hash_map,
1986            expn_hash_map: Default::default(),
1987            alloc_decoding_state,
1988            cnum,
1989            cnum_map,
1990            dep_kind,
1991            source: Arc::new(source),
1992            private_dep,
1993            host_hash,
1994            used: false,
1995            extern_crate: None,
1996            hygiene_context: Default::default(),
1997            def_key_cache: Default::default(),
1998        };
1999
2000        cdata.incoherent_impls = cdata
2001            .root
2002            .incoherent_impls
2003            .decode((&cdata, tcx))
2004            .map(|incoherent_impls| {
2005                (incoherent_impls.self_ty.decode((&cdata, tcx)), incoherent_impls.impls)
2006            })
2007            .collect();
2008
2009        cdata
2010    }
2011
2012    pub(crate) fn dependencies(&self) -> impl Iterator<Item = CrateNum> {
2013        self.cnum_map.iter().copied()
2014    }
2015
2016    pub(crate) fn target_modifiers(&self) -> TargetModifiers {
2017        self.root.decode_target_modifiers(&self.blob).collect()
2018    }
2019
2020    pub(crate) fn enabled_denied_partial_mitigations(&self) -> DeniedPartialMitigations {
2021        self.root.decode_denied_partial_mitigations(&self.blob).collect()
2022    }
2023
2024    /// Keep `new_extern_crate` if it looks better in diagnostics
2025    pub(crate) fn update_extern_crate_diagnostics(
2026        &mut self,
2027        new_extern_crate: ExternCrate,
2028    ) -> bool {
2029        let update =
2030            self.extern_crate.as_ref().is_none_or(|old| old.rank() < new_extern_crate.rank());
2031        if update {
2032            self.extern_crate = Some(new_extern_crate);
2033        }
2034        update
2035    }
2036
2037    pub(crate) fn source(&self) -> &CrateSource {
2038        &*self.source
2039    }
2040
2041    pub(crate) fn dep_kind(&self) -> CrateDepKind {
2042        self.dep_kind
2043    }
2044
2045    pub(crate) fn set_dep_kind(&mut self, dep_kind: CrateDepKind) {
2046        self.dep_kind = dep_kind;
2047    }
2048
2049    pub(crate) fn update_and_private_dep(&mut self, private_dep: bool) {
2050        self.private_dep &= private_dep;
2051    }
2052
2053    pub(crate) fn used(&self) -> bool {
2054        self.used
2055    }
2056
2057    pub(crate) fn required_panic_strategy(&self) -> Option<PanicStrategy> {
2058        self.root.required_panic_strategy
2059    }
2060
2061    pub(crate) fn needs_panic_runtime(&self) -> bool {
2062        self.root.needs_panic_runtime
2063    }
2064
2065    pub(crate) fn is_private_dep(&self) -> bool {
2066        self.private_dep
2067    }
2068
2069    pub(crate) fn is_panic_runtime(&self) -> bool {
2070        self.root.panic_runtime
2071    }
2072
2073    pub(crate) fn is_profiler_runtime(&self) -> bool {
2074        self.root.profiler_runtime
2075    }
2076
2077    pub(crate) fn is_compiler_builtins(&self) -> bool {
2078        self.root.compiler_builtins
2079    }
2080
2081    pub(crate) fn needs_allocator(&self) -> bool {
2082        self.root.needs_allocator
2083    }
2084
2085    pub(crate) fn has_global_allocator(&self) -> bool {
2086        self.root.has_global_allocator
2087    }
2088
2089    pub(crate) fn has_alloc_error_handler(&self) -> bool {
2090        self.root.has_alloc_error_handler
2091    }
2092
2093    pub(crate) fn has_default_lib_allocator(&self) -> bool {
2094        self.root.has_default_lib_allocator
2095    }
2096
2097    pub(crate) fn is_proc_macro_crate(&self) -> bool {
2098        self.root.is_proc_macro_crate()
2099    }
2100
2101    pub(crate) fn proc_macros_for_crate(
2102        &self,
2103        tcx: TyCtxt<'_>,
2104        krate: CrateNum,
2105    ) -> impl Iterator<Item = DefId> {
2106        gen move {
2107            if let Some(data) = &self.root.proc_macro_data {
2108                for def_id in
2109                    data.macros.decode((self, tcx)).map(move |(index, _)| DefId { index, krate })
2110                {
2111                    yield def_id;
2112                }
2113            }
2114        }
2115    }
2116
2117    pub(crate) fn name(&self) -> Symbol {
2118        self.root.header.name
2119    }
2120
2121    pub(crate) fn hash(&self) -> Svh {
2122        self.blob.get_crate_hash()
2123    }
2124
2125    pub(crate) fn has_async_drops(&self) -> bool {
2126        self.root.tables.adt_async_destructor.len > 0
2127    }
2128
2129    fn num_def_ids(&self) -> usize {
2130        self.root.tables.def_keys.size()
2131    }
2132
2133    fn local_def_id(&self, index: DefIndex) -> DefId {
2134        DefId { krate: self.cnum, index }
2135    }
2136
2137    // Translate a DefId from the current compilation environment to a DefId
2138    // for an external crate.
2139    fn reverse_translate_def_id(&self, did: DefId) -> Option<DefId> {
2140        for (local, &global) in self.cnum_map.iter_enumerated() {
2141            if global == did.krate {
2142                return Some(DefId { krate: local, index: did.index });
2143            }
2144        }
2145
2146        None
2147    }
2148}