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