]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | // The crate store - a central repo for information collected about external |
2 | // crates and libraries | |
3 | ||
9fa01778 | 4 | use crate::schema; |
e74abb32 | 5 | use rustc::dep_graph::DepNodeIndex; |
94b46f34 | 6 | use rustc::hir::def_id::{CrateNum, DefIndex}; |
ea8adc8c | 7 | use rustc::hir::map::definitions::DefPathTable; |
e74abb32 | 8 | use rustc::middle::cstore::{CrateSource, DepKind, ExternCrate}; |
94b46f34 | 9 | use rustc::mir::interpret::AllocDecodingState; |
e74abb32 XL |
10 | use rustc_index::vec::IndexVec; |
11 | use rustc::util::nodemap::FxHashMap; | |
12 | use rustc_data_structures::sync::{Lrc, Lock, MetadataRef, Once, AtomicCell}; | |
13 | use rustc_data_structures::svh::Svh; | |
94b46f34 | 14 | use syntax::ast; |
e74abb32 XL |
15 | use syntax::edition::Edition; |
16 | use syntax_expand::base::SyntaxExtension; | |
3157f602 | 17 | use syntax_pos; |
e74abb32 | 18 | use proc_macro::bridge::client::ProcMacro; |
223e47cc | 19 | |
9fa01778 | 20 | pub use crate::cstore_impl::{provide, provide_extern}; |
8bb4bdeb | 21 | |
223e47cc LB |
22 | // A map from external crate numbers (as decoded from some crate file) to |
23 | // local crate numbers (as generated during this session). Each external | |
24 | // crate may refer to types in other external crates, and each has their | |
25 | // own crate numbers. | |
e74abb32 | 26 | crate type CrateNumMap = IndexVec<CrateNum, CrateNum>; |
223e47cc | 27 | |
e74abb32 | 28 | crate struct MetadataBlob(pub MetadataRef); |
223e47cc | 29 | |
b7449926 XL |
30 | /// Holds information about a syntax_pos::SourceFile imported from another crate. |
31 | /// See `imported_source_files()` for more information. | |
e74abb32 | 32 | crate struct ImportedSourceFile { |
b7449926 | 33 | /// This SourceFile's byte-offset within the source_map of its original crate |
3157f602 | 34 | pub original_start_pos: syntax_pos::BytePos, |
b7449926 | 35 | /// The end of this SourceFile within the source_map of its original crate |
3157f602 | 36 | pub original_end_pos: syntax_pos::BytePos, |
b7449926 XL |
37 | /// The imported SourceFile's representation within the local source_map |
38 | pub translated_source_file: Lrc<syntax_pos::SourceFile>, | |
c34b1796 AL |
39 | } |
40 | ||
e74abb32 XL |
41 | crate struct CrateMetadata { |
42 | /// The primary crate data - binary metadata blob. | |
43 | crate blob: MetadataBlob, | |
4462d4a0 | 44 | |
e74abb32 | 45 | // --- Some data pre-decoded from the metadata blob, usually for performance --- |
e9174d1e | 46 | |
e74abb32 XL |
47 | /// Properties of the whole crate. |
48 | /// NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this | |
49 | /// lifetime is only used behind `Lazy`, and therefore acts like an | |
50 | /// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt` | |
51 | /// is being used to decode those values. | |
52 | crate root: schema::CrateRoot<'static>, | |
e1599b0c | 53 | /// For each definition in this crate, we encode a key. When the |
a7813a04 | 54 | /// crate is loaded, we read all the keys and put them in this |
9fa01778 | 55 | /// hashmap, which gives the reverse mapping. This allows us to |
a7813a04 XL |
56 | /// quickly retrace a `DefPath`, which is needed for incremental |
57 | /// compilation support. | |
e74abb32 XL |
58 | crate def_path_table: DefPathTable, |
59 | /// Trait impl data. | |
60 | /// FIXME: Used only from queries and can use query cache, | |
61 | /// so pre-decoding can probably be avoided. | |
62 | crate trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>, | |
63 | /// Proc macro descriptions for this crate, if it's a proc macro crate. | |
64 | crate raw_proc_macros: Option<&'static [ProcMacro]>, | |
65 | /// Source maps for code from the crate. | |
66 | crate source_map_import_info: Once<Vec<ImportedSourceFile>>, | |
67 | /// Used for decoding interpret::AllocIds in a cached & thread-safe manner. | |
68 | crate alloc_decoding_state: AllocDecodingState, | |
69 | /// The `DepNodeIndex` of the `DepNode` representing this upstream crate. | |
70 | /// It is initialized on the first access in `get_crate_dep_node_index()`. | |
71 | /// Do not access the value directly, as it might not have been initialized yet. | |
72 | /// The field must always be initialized to `DepNodeIndex::INVALID`. | |
73 | crate dep_node_index: AtomicCell<DepNodeIndex>, | |
74 | ||
75 | // --- Other significant crate properties --- | |
76 | ||
77 | /// ID of this crate, from the current compilation session's point of view. | |
78 | crate cnum: CrateNum, | |
79 | /// Maps crate IDs as they are were seen from this crate's compilation sessions into | |
80 | /// IDs as they are seen from the current compilation session. | |
81 | crate cnum_map: CrateNumMap, | |
82 | /// Same ID set as `cnum_map` plus maybe some injected crates like panic runtime. | |
83 | crate dependencies: Lock<Vec<CrateNum>>, | |
84 | /// How to link (or not link) this crate to the currently compiled crate. | |
85 | crate dep_kind: Lock<DepKind>, | |
86 | /// Filesystem location of this crate. | |
87 | crate source: CrateSource, | |
48663c56 XL |
88 | /// Whether or not this crate should be consider a private dependency |
89 | /// for purposes of the 'exported_private_dependencies' lint | |
e74abb32 XL |
90 | crate private_dep: bool, |
91 | /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`. | |
92 | crate host_hash: Option<Svh>, | |
e1599b0c | 93 | |
e74abb32 | 94 | // --- Data used only for improving diagnostics --- |
e1599b0c | 95 | |
e74abb32 XL |
96 | /// Information about the `extern crate` item or path that caused this crate to be loaded. |
97 | /// If this is `None`, then the crate was injected (e.g., by the allocator). | |
98 | crate extern_crate: Lock<Option<ExternCrate>>, | |
223e47cc LB |
99 | } |
100 | ||
e74abb32 | 101 | #[derive(Clone)] |
1a4d82fc | 102 | pub struct CStore { |
e74abb32 | 103 | metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>, |
1a4d82fc JJ |
104 | } |
105 | ||
b7449926 | 106 | pub enum LoadedMacro { |
e74abb32 | 107 | MacroDef(ast::Item, Edition), |
e1599b0c | 108 | ProcMacro(SyntaxExtension), |
b7449926 XL |
109 | } |
110 | ||
e74abb32 XL |
111 | impl Default for CStore { |
112 | fn default() -> Self { | |
1a4d82fc | 113 | CStore { |
94b46f34 XL |
114 | // We add an empty entry for LOCAL_CRATE (which maps to zero) in |
115 | // order to make array indices in `metas` match with the | |
116 | // corresponding `CrateNum`. This first entry will always remain | |
117 | // `None`. | |
e74abb32 | 118 | metas: IndexVec::from_elem_n(None, 1), |
1a4d82fc JJ |
119 | } |
120 | } | |
e74abb32 | 121 | } |
223e47cc | 122 | |
e74abb32 XL |
123 | impl CStore { |
124 | crate fn alloc_new_crate_num(&mut self) -> CrateNum { | |
125 | self.metas.push(None); | |
126 | CrateNum::new(self.metas.len() - 1) | |
1a4d82fc | 127 | } |
223e47cc | 128 | |
e74abb32 XL |
129 | crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata { |
130 | self.metas[cnum].as_ref() | |
48663c56 | 131 | .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum)) |
1a4d82fc | 132 | } |
223e47cc | 133 | |
e74abb32 XL |
134 | crate fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) { |
135 | assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry"); | |
136 | self.metas[cnum] = Some(Lrc::new(data)); | |
223e47cc | 137 | } |
223e47cc | 138 | |
e74abb32 XL |
139 | crate fn iter_crate_data<I>(&self, mut i: I) |
140 | where I: FnMut(CrateNum, &CrateMetadata) | |
1a4d82fc | 141 | { |
e74abb32 | 142 | for (k, v) in self.metas.iter_enumerated() { |
2c00a5a8 XL |
143 | if let &Some(ref v) = v { |
144 | i(k, v); | |
145 | } | |
1a4d82fc JJ |
146 | } |
147 | } | |
223e47cc | 148 | |
e74abb32 | 149 | crate fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> { |
3157f602 XL |
150 | let mut ordering = Vec::new(); |
151 | self.push_dependencies_in_postorder(&mut ordering, krate); | |
152 | ordering.reverse(); | |
153 | ordering | |
154 | } | |
155 | ||
e74abb32 | 156 | crate fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) { |
c30ab7b3 SL |
157 | if ordering.contains(&krate) { |
158 | return; | |
159 | } | |
3157f602 XL |
160 | |
161 | let data = self.get_crate_data(krate); | |
94b46f34 | 162 | for &dep in data.dependencies.borrow().iter() { |
3157f602 XL |
163 | if dep != krate { |
164 | self.push_dependencies_in_postorder(ordering, dep); | |
165 | } | |
166 | } | |
167 | ||
168 | ordering.push(krate); | |
169 | } | |
170 | ||
e74abb32 | 171 | crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> { |
1a4d82fc | 172 | let mut ordering = Vec::new(); |
e74abb32 | 173 | for (num, v) in self.metas.iter_enumerated() { |
2c00a5a8 XL |
174 | if let &Some(_) = v { |
175 | self.push_dependencies_in_postorder(&mut ordering, num); | |
176 | } | |
1a4d82fc | 177 | } |
ea8adc8c | 178 | return ordering |
223e47cc | 179 | } |
1a4d82fc | 180 | } |