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