From 9cfe1a5b4b9464ea0bfb271201bb803305cc94d4 Mon Sep 17 00:00:00 2001 From: Joshua Nelson <jyn514@gmail.com> Date: Mon, 10 Aug 2020 00:09:22 -0400 Subject: [PATCH 1/2] Remove fake IDs in rustdoc They're confusing, cause crashes, and aren't necessary. --- src/librustdoc/clean/auto_trait.rs | 2 +- src/librustdoc/clean/blanket_impl.rs | 2 +- src/librustdoc/clean/types.rs | 28 +--------- src/librustdoc/core.rs | 54 ++----------------- .../passes/collect_intra_doc_links.rs | 5 +- 5 files changed, 8 insertions(+), 83 deletions(-) diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 9c44d27447db..e4758665c543 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -122,7 +122,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { name: None, attrs: Default::default(), visibility: Inherited, - def_id: self.cx.next_def_id(param_env_def_id.krate), + def_id: param_env_def_id, stability: None, deprecation: None, inner: ImplItem(Impl { diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 3d2785541bee..cca9532f9629 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -96,7 +96,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { name: None, attrs: Default::default(), visibility: Inherited, - def_id: self.cx.next_def_id(impl_def_id.krate), + def_id: impl_def_id, stability: None, deprecation: None, inner: ImplItem(Impl { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 50eca75d7cab..6e96669f78af 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1,6 +1,5 @@ use std::cell::RefCell; use std::default::Default; -use std::fmt; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; use std::num::NonZeroU32; @@ -70,7 +69,7 @@ pub struct ExternalCrate { /// Anything with a source location and set of attributes and, optionally, a /// name. That is, anything that can be documented. This doesn't correspond /// directly to the AST's concept of an item; it's a strict superset. -#[derive(Clone)] +#[derive(Clone, Debug)] pub struct Item { /// Stringified span pub source: Span, @@ -84,24 +83,6 @@ pub struct Item { pub deprecation: Option<Deprecation>, } -impl fmt::Debug for Item { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let fake = self.is_fake(); - let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id }; - - fmt.debug_struct("Item") - .field("source", &self.source) - .field("name", &self.name) - .field("attrs", &self.attrs) - .field("inner", &self.inner) - .field("visibility", &self.visibility) - .field("def_id", def_id) - .field("stability", &self.stability) - .field("deprecation", &self.deprecation) - .finish() - } -} - impl Item { /// Finds the `doc` attribute as a NameValue and returns the corresponding /// value found. @@ -230,13 +211,6 @@ impl Item { _ => false, } } - - /// See comments on next_def_id - pub fn is_fake(&self) -> bool { - MAX_DEF_ID.with(|m| { - m.borrow().get(&self.def_id.krate).map(|id| self.def_id >= *id).unwrap_or(false) - }) - } } #[derive(Clone, Debug)] diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index cbd0ca0de641..01ac69d6dc87 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -6,7 +6,7 @@ use rustc_errors::emitter::{Emitter, EmitterWriter}; use rustc_errors::json::JsonEmitter; use rustc_feature::UnstableFeatures; use rustc_hir::def::{Namespace::TypeNS, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::HirId; use rustc_hir::{ intravisit::{self, NestedVisitorMap, Visitor}, @@ -14,7 +14,6 @@ use rustc_hir::{ }; use rustc_interface::interface; use rustc_middle::hir::map::Map; -use rustc_middle::middle::cstore::CrateStore; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::{Ty, TyCtxt}; use rustc_resolve as resolve; @@ -31,7 +30,7 @@ use std::mem; use std::rc::Rc; use crate::clean; -use crate::clean::{AttributesExt, MAX_DEF_ID}; +use crate::clean::AttributesExt; use crate::config::RenderInfo; use crate::config::{Options as RustdocOptions, RenderOptions}; use crate::passes::{self, Condition::*, ConditionalPass}; @@ -61,8 +60,6 @@ pub struct DocContext<'tcx> { pub ct_substs: RefCell<FxHashMap<DefId, clean::Constant>>, /// Table synthetic type parameter for `impl Trait` in argument position -> bounds pub impl_trait_bounds: RefCell<FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>>, - pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>, - pub all_fake_def_ids: RefCell<FxHashSet<DefId>>, /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`. // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set. pub generated_synthetics: RefCell<FxHashSet<(Ty<'tcx>, DefId)>>, @@ -107,50 +104,9 @@ impl<'tcx> DocContext<'tcx> { r } - // This is an ugly hack, but it's the simplest way to handle synthetic impls without greatly - // refactoring either librustdoc or librustc_middle. In particular, allowing new DefIds 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' def ids, which start immediately after the last DefId. - // In the Debug impl for clean::Item, we explicitly check for fake - // def ids, as we'll end up with a panic if we use the DefId Debug impl for fake DefIds - pub fn next_def_id(&self, crate_num: CrateNum) -> DefId { - let start_def_id = { - let next_id = if crate_num == LOCAL_CRATE { - self.tcx.hir().definitions().def_path_table().next_id() - } else { - self.enter_resolver(|r| r.cstore().def_path_table(crate_num).next_id()) - }; - - DefId { krate: crate_num, index: next_id } - }; - - let mut fake_ids = self.fake_def_ids.borrow_mut(); - - let def_id = *fake_ids.entry(crate_num).or_insert(start_def_id); - fake_ids.insert( - crate_num, - DefId { krate: crate_num, index: DefIndex::from(def_id.index.index() + 1) }, - ); - - MAX_DEF_ID.with(|m| { - m.borrow_mut().entry(def_id.krate).or_insert(start_def_id); - }); - - self.all_fake_def_ids.borrow_mut().insert(def_id); - - def_id - } - - /// Like the function of the same name on the HIR map, but skips calling it on fake DefIds. - /// (This avoids a slice-index-out-of-bounds panic.) + /// Like the function of the same name on the HIR map, but more concisely. pub fn as_local_hir_id(&self, def_id: DefId) -> Option<HirId> { - if self.all_fake_def_ids.borrow().contains(&def_id) { - None - } else { - def_id.as_local().map(|def_id| self.tcx.hir().as_local_hir_id(def_id)) - } + def_id.as_local().map(|def_id| self.tcx.hir().as_local_hir_id(def_id)) } pub fn stability(&self, id: HirId) -> Option<attr::Stability> { @@ -486,8 +442,6 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt lt_substs: Default::default(), ct_substs: Default::default(), impl_trait_bounds: Default::default(), - fake_def_ids: Default::default(), - all_fake_def_ids: Default::default(), generated_synthetics: Default::default(), auto_traits: tcx .all_traits(LOCAL_CRATE) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f84486347afc..2cc23d3b8e0b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -460,10 +460,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { fn fold_item(&mut self, mut item: Item) -> Option<Item> { use rustc_middle::ty::DefIdTree; - let parent_node = if item.is_fake() { - // FIXME: is this correct? - None - } else { + let parent_node = { let mut current = item.def_id; // The immediate parent might not always be a module. // Find the first parent which is. From 758829e927e58d674d9ec27f3525c401b97f9926 Mon Sep 17 00:00:00 2001 From: Joshua Nelson <jyn514@gmail.com> Date: Mon, 10 Aug 2020 01:04:22 -0400 Subject: [PATCH 2/2] Don't ignore impls that have already been seen This code path was never taken before because all the ids were fake. So the ids would never have been seen before. --- src/librustdoc/passes/collect_trait_impls.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 3000afde0c25..d1b3acd24da4 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -76,7 +76,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { let impls = get_auto_trait_and_blanket_impls(cx, self_ty, def_id); let mut renderinfo = cx.renderinfo.borrow_mut(); - new_items.extend(impls.filter(|i| renderinfo.inlined.insert(i.def_id))); + new_items.extend(impls.inspect(|i| { renderinfo.inlined.insert(i.def_id); })); } } }