1 // The crate store - a central repo for information collected about external
2 // crates and libraries
4 use crate::rmeta::CrateMetadata;
6 use rustc_data_structures::sync::Lrc;
7 use rustc_index::vec::IndexVec;
8 use rustc::hir::def_id::CrateNum;
10 use syntax::edition::Edition;
11 use syntax::expand::allocator::AllocatorKind;
12 use syntax_expand::base::SyntaxExtension;
14 pub use crate::rmeta::{provide, provide_extern};
18 metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
19 crate injected_panic_runtime: Option<CrateNum>,
20 crate allocator_kind: Option<AllocatorKind>,
23 pub enum LoadedMacro {
24 MacroDef(ast::Item, Edition),
25 ProcMacro(SyntaxExtension),
28 impl Default for CStore {
29 fn default() -> Self {
31 // We add an empty entry for LOCAL_CRATE (which maps to zero) in
32 // order to make array indices in `metas` match with the
33 // corresponding `CrateNum`. This first entry will always remain
35 metas: IndexVec::from_elem_n(None, 1),
36 injected_panic_runtime: None,
43 crate fn alloc_new_crate_num(&mut self) -> CrateNum {
44 self.metas.push(None);
45 CrateNum::new(self.metas.len() - 1)
48 crate fn get_crate_data(&self, cnum: CrateNum) -> &CrateMetadata {
49 self.metas[cnum].as_ref()
50 .unwrap_or_else(|| panic!("Failed to get crate data for {:?}", cnum))
53 crate fn set_crate_data(&mut self, cnum: CrateNum, data: CrateMetadata) {
54 assert!(self.metas[cnum].is_none(), "Overwriting crate metadata entry");
55 self.metas[cnum] = Some(Lrc::new(data));
58 crate fn iter_crate_data<I>(&self, mut i: I)
59 where I: FnMut(CrateNum, &CrateMetadata)
61 for (k, v) in self.metas.iter_enumerated() {
62 if let &Some(ref v) = v {
68 crate fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
69 let mut ordering = Vec::new();
70 self.push_dependencies_in_postorder(&mut ordering, krate);
75 crate fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) {
76 if ordering.contains(&krate) {
80 let data = self.get_crate_data(krate);
81 for &dep in data.dependencies.borrow().iter() {
83 self.push_dependencies_in_postorder(ordering, dep);
90 crate fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
91 let mut ordering = Vec::new();
92 for (num, v) in self.metas.iter_enumerated() {
94 self.push_dependencies_in_postorder(&mut ordering, num);