]> git.lizzy.rs Git - rust.git/blob - src/librustc_metadata/cstore.rs
Tweak multiple allocators error
[rust.git] / src / librustc_metadata / cstore.rs
1 // The crate store - a central repo for information collected about external
2 // crates and libraries
3
4 use crate::rmeta::CrateMetadata;
5
6 use rustc_data_structures::sync::Lrc;
7 use rustc_index::vec::IndexVec;
8 use rustc::hir::def_id::CrateNum;
9 use syntax::ast;
10 use syntax::edition::Edition;
11 use syntax::expand::allocator::AllocatorKind;
12 use syntax_expand::base::SyntaxExtension;
13
14 pub use crate::rmeta::{provide, provide_extern};
15
16 #[derive(Clone)]
17 pub struct CStore {
18     metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
19     crate injected_panic_runtime: Option<CrateNum>,
20     crate allocator_kind: Option<AllocatorKind>,
21 }
22
23 pub enum LoadedMacro {
24     MacroDef(ast::Item, Edition),
25     ProcMacro(SyntaxExtension),
26 }
27
28 impl Default for CStore {
29     fn default() -> Self {
30         CStore {
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
34             // `None`.
35             metas: IndexVec::from_elem_n(None, 1),
36             injected_panic_runtime: None,
37             allocator_kind: None,
38         }
39     }
40 }
41
42 impl CStore {
43     crate fn alloc_new_crate_num(&mut self) -> CrateNum {
44         self.metas.push(None);
45         CrateNum::new(self.metas.len() - 1)
46     }
47
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))
51     }
52
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));
56     }
57
58     crate fn iter_crate_data<I>(&self, mut i: I)
59         where I: FnMut(CrateNum, &CrateMetadata)
60     {
61         for (k, v) in self.metas.iter_enumerated() {
62             if let &Some(ref v) = v {
63                 i(k, v);
64             }
65         }
66     }
67
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);
71         ordering.reverse();
72         ordering
73     }
74
75     crate fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) {
76         if ordering.contains(&krate) {
77             return;
78         }
79
80         let data = self.get_crate_data(krate);
81         for &dep in data.dependencies.borrow().iter() {
82             if dep != krate {
83                 self.push_dependencies_in_postorder(ordering, dep);
84             }
85         }
86
87         ordering.push(krate);
88     }
89
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() {
93             if let &Some(_) = v {
94                 self.push_dependencies_in_postorder(&mut ordering, num);
95             }
96         }
97         return ordering
98     }
99 }