about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_metadata/creader.rs5
-rw-r--r--src/librustc_metadata/cstore.rs42
2 files changed, 24 insertions, 23 deletions
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 7efcedd73ed..87b3a2dc69f 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -51,7 +51,6 @@ pub struct Library {
 pub struct CrateLoader<'a> {
     pub sess: &'a Session,
     cstore: &'a CStore,
-    next_crate_num: CrateNum,
     local_crate_name: Symbol,
 }
 
@@ -102,7 +101,6 @@ impl<'a> CrateLoader<'a> {
         CrateLoader {
             sess,
             cstore,
-            next_crate_num: cstore.next_crate_num(),
             local_crate_name: Symbol::intern(local_crate_name),
         }
     }
@@ -198,8 +196,7 @@ impl<'a> CrateLoader<'a> {
         self.verify_no_symbol_conflicts(span, &crate_root);
 
         // Claim this crate number and cache it
-        let cnum = self.next_crate_num;
-        self.next_crate_num = CrateNum::from_u32(cnum.as_u32() + 1);
+        let cnum = self.cstore.alloc_new_crate_num();
 
         // Stash paths for top-most crate locally if necessary.
         let crate_paths = if root.is_none() {
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index f4d4bd35893..9bbce563b61 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -97,32 +97,34 @@ pub struct CStore {
 impl CStore {
     pub fn new(metadata_loader: Box<MetadataLoader + Sync>) -> CStore {
         CStore {
-            metas: RwLock::new(IndexVec::new()),
+            // We add an empty entry for LOCAL_CRATE (which maps to zero) in
+            // order to make array indices in `metas` match with the
+            // corresponding `CrateNum`. This first entry will always remain
+            // `None`.
+            metas: RwLock::new(IndexVec::from_elem_n(None, 1)),
             extern_mod_crate_map: Lock::new(FxHashMap()),
             metadata_loader,
         }
     }
 
-    /// You cannot use this function to allocate a CrateNum in a thread-safe manner.
-    /// It is currently only used in CrateLoader which is single-threaded code.
-    pub fn next_crate_num(&self) -> CrateNum {
-        CrateNum::new(self.metas.borrow().len() + 1)
+    pub(super) fn alloc_new_crate_num(&self) -> CrateNum {
+        let mut metas = self.metas.borrow_mut();
+        let cnum = CrateNum::new(metas.len());
+        metas.push(None);
+        cnum
     }
 
-    pub fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
+    pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
         self.metas.borrow()[cnum].clone().unwrap()
     }
 
-    pub fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
-        use rustc_data_structures::indexed_vec::Idx;
-        let mut met = self.metas.borrow_mut();
-        while met.len() <= cnum.index() {
-            met.push(None);
-        }
-        met[cnum] = Some(data);
+    pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
+        let mut metas = self.metas.borrow_mut();
+        assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
+        metas[cnum] = Some(data);
     }
 
-    pub fn iter_crate_data<I>(&self, mut i: I)
+    pub(super) fn iter_crate_data<I>(&self, mut i: I)
         where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
     {
         for (k, v) in self.metas.borrow().iter_enumerated() {
@@ -132,14 +134,16 @@ impl CStore {
         }
     }
 
-    pub fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
+    pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
         let mut ordering = Vec::new();
         self.push_dependencies_in_postorder(&mut ordering, krate);
         ordering.reverse();
         ordering
     }
 
-    pub fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) {
+    pub(super) fn push_dependencies_in_postorder(&self,
+                                                 ordering: &mut Vec<CrateNum>,
+                                                 krate: CrateNum) {
         if ordering.contains(&krate) {
             return;
         }
@@ -154,7 +158,7 @@ impl CStore {
         ordering.push(krate);
     }
 
-    pub fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
+    pub(super) fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
         let mut ordering = Vec::new();
         for (num, v) in self.metas.borrow().iter_enumerated() {
             if let &Some(_) = v {
@@ -164,11 +168,11 @@ impl CStore {
         return ordering
     }
 
-    pub fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
+    pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
         self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
     }
 
-    pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
+    pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
         self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
     }
 }