- /// Create a new "fake" [`DefId`].
- ///
- /// This is an ugly hack, but it's the simplest way to handle synthetic impls without greatly
- /// refactoring either rustdoc or [`rustc_middle`]. In particular, allowing new [`DefId`]s
- /// to be registered after the AST is constructed would require storing the [`DefId`] mapping
- /// in a [`RefCell`], decreasing the performance for normal compilation for very little gain.
- ///
- /// Instead, we construct "fake" [`DefId`]s, which start immediately after the last `DefId`.
- /// In the [`Debug`] impl for [`clean::Item`], we explicitly check for fake `DefId`s,
- /// as we'll end up with a panic if we use the `DefId` `Debug` impl for fake `DefId`s.
- ///
- /// [`RefCell`]: std::cell::RefCell
- /// [`Debug`]: std::fmt::Debug
- /// [`clean::Item`]: crate::clean::types::Item
- crate fn next_def_id(&mut self, crate_num: CrateNum) -> DefId {
- let def_index = match self.fake_def_ids.entry(crate_num) {
- Entry::Vacant(e) => {
- let num_def_idx = {
- let num_def_idx = if crate_num == LOCAL_CRATE {
- self.tcx.hir().definitions().def_path_table().num_def_ids()
- } else {
- self.resolver.borrow_mut().access(|r| r.cstore().num_def_ids(crate_num))
- };
-
- DefIndex::from_usize(num_def_idx)
- };
-
- MAX_DEF_IDX.with(|m| {
- m.borrow_mut().insert(crate_num, num_def_idx);
- });
- e.insert(num_def_idx)
- }
- Entry::Occupied(e) => e.into_mut(),
- };
- *def_index = *def_index + 1;
-
- DefId { krate: crate_num, index: *def_index }
- }
-