Change:
While investigating the root cause(s) of and discussing (in the IRC chat room) the use of a hashmap mapping crate-numbers to crate-metadata, "why is that not an ?" One word: Legacy. Big time: the field has been a hashmap ever since was introduced, 6.5 years ago in () It should be a useful (and hopefully simple?) exercise to replace the hashmap that is with an .
So is it just replacing the type with? If sow what is the equivalent for insert?
Should be as simple as that
The only way I am seeing to add to an IndexVec is to push to the end at index == len But the hashmap uses the ability to insert at an arbitrary index: So I don't quite see how to make the conversion.
from my quick skimming, is only called from one place: , here: The in that context is always the steadily incremented . So I would suggest removing entirely, and replacing it with a some method that indeed pushes to the end at index == len, as you state, since it seems that will have the same end effect.
BTW if one really did need to support overwriting for arbitrary s, that is easy too, as long as they already exist in the , since supports the method that underlying : ; but I don't think we will need that in this case.
Maybe you want an ?
That's not 100% correct. Crate numbers are assigned in preorder - if a crate (say ) has a dependency (say ), then will get the earlier crate number, then will be loaded, and only then will the metadata for be assigned. But it's ok to use an to handle this.
You are right. I overlooked the fact that we 1. first increment the crate num (reserving the number, like for in your example), then 2. call (which may recursively re-enter ), before finally 3. calling at the end.
Ok, what is the best incantation to test this locally? In the meantime I will open a pr.

Discussion:
} pub struct CStore { <del> metas: RefCell<FxHashMap<CrateNum, Rc<CrateMetadata>>>, </del> <ins> metas: RefCell<IndexVec<CrateNum, Option<Rc<CrateMetadata>>>>, </ins> /// Map from NodeId's of local extern crate statements to crate numbers extern_mod_crate_map: RefCell<NodeMap<CrateNum>>, pub metadata_loader: Box<MetadataLoader>,

impl CStore { pub fn new(metadata_loader: Box<MetadataLoader>) -> CStore { CStore { <del> metas: RefCell::new(FxHashMap()), </del> <ins> metas: RefCell::new(IndexVec::new()), </ins> extern_mod_crate_map: RefCell::new(FxHashMap()), metadata_loader, }

} pub fn get_crate_data(&self, cnum: CrateNum) -> Rc<CrateMetadata> { <del> self.metas.borrow().get(&cnum).unwrap().clone() </del> <ins> self.metas.borrow()[cnum].clone().unwrap() </ins> } pub fn set_crate_data(&self, cnum: CrateNum, data: Rc<CrateMetadata>) { <del> self.metas.borrow_mut().insert(cnum, data); </del> <ins> 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); </ins> } pub fn iter_crate_data<I>(&self, mut i: I) where I: FnMut(CrateNum, &Rc<CrateMetadata>) { <del> for (&k, v) in self.metas.borrow().iter() { i(k, v); </del> <ins> for (k, v) in self.metas.borrow().iter_enumerated() { if let &Some(ref v) = v { i(k, v); } </ins> } }

pub fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> { let mut ordering = Vec::new(); <del> for (&num, _) in self.metas.borrow().iter() { self.push_dependencies_in_postorder(&mut ordering, num); </del> <ins> for (num, v) in self.metas.borrow().iter_enumerated() { if let &Some(_) = v { self.push_dependencies_in_postorder(&mut ordering, num); } </ins> } return ordering }