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