diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 0f77de9fb250f..647d735fb8632 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -87,11 +87,6 @@ impl DefPathTable { hash } - /// Used by librustdoc for fake DefIds. - pub fn num_def_ids(&self) -> usize { - self.index_to_key.len() - } - pub fn enumerated_keys_and_path_hashes( &self, ) -> impl Iterator + '_ { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 2ade1bb4f95de..d74fef0045f51 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1885,10 +1885,6 @@ impl CrateMetadata { self.root.hash } - fn num_def_ids(&self) -> usize { - self.root.tables.def_keys.size() - } - fn local_def_id(&self, index: DefIndex) -> DefId { DefId { krate: self.cnum, index } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index bebee9dac3b73..8595a70dd9478 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -461,10 +461,6 @@ impl CStore { self.get_crate_data(def_id.krate).module_expansion(def_id.index, sess) } - pub fn num_def_ids(&self, cnum: CrateNum) -> usize { - self.get_crate_data(cnum).num_def_ids() - } - pub fn item_attrs(&self, def_id: DefId, sess: &Session) -> Vec { self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess).collect() } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index dbdf2e4bbb0f9..3bfc9fea62e90 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -113,7 +113,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { name: None, attrs: Default::default(), visibility: Inherited, - def_id: self.cx.next_def_id(item_def_id.krate), + def_id: FakeDefId::new_fake(item_def_id.krate), kind: box ImplItem(Impl { span: Span::dummy(), unsafety: hir::Unsafety::Normal, diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index f5c4034a61de2..68856f82fe94c 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -97,7 +97,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: FakeDefId::new_fake(item_def_id.krate), kind: box ImplItem(Impl { span: self.cx.tcx.def_span(impl_def_id).clean(self.cx), unsafety: hir::Unsafety::Normal, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 6ad635012b134..5974cd878dd0c 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -15,7 +15,7 @@ use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -use crate::clean::{self, Attributes, AttributesExt, GetDefId, ToSource}; +use crate::clean::{self, Attributes, AttributesExt, FakeDefId, GetDefId, ToSource}; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -121,7 +121,7 @@ crate fn try_inline( }; let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone); - cx.inlined.insert(did); + cx.inlined.insert(did.into()); ret.push(clean::Item::from_def_id_and_attrs_and_parts( did, Some(name), @@ -332,7 +332,7 @@ crate fn build_impl( attrs: Option>, ret: &mut Vec, ) { - if !cx.inlined.insert(did) { + if !cx.inlined.insert(did.into()) { return; } @@ -470,7 +470,7 @@ fn build_module( items.push(clean::Item { name: None, attrs: box clean::Attributes::default(), - def_id: cx.next_def_id(did.krate), + def_id: FakeDefId::new_fake(did.krate), visibility: clean::Public, kind: box clean::ImportItem(clean::Import::new_simple( item.ident.name, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 33df9ea3f3e0c..411cfab9f06a0 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -533,7 +533,8 @@ impl Clean for hir::Generics<'_> { match param.kind { GenericParamDefKind::Lifetime => unreachable!(), GenericParamDefKind::Type { did, ref bounds, .. } => { - cx.impl_trait_bounds.insert(did.into(), bounds.clone()); + cx.impl_trait_bounds + .insert(FakeDefId::new_real(did).into(), bounds.clone()); } GenericParamDefKind::Const { .. } => unreachable!(), } @@ -614,7 +615,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx .collect::>(); // param index -> [(DefId of trait, associated type name, type)] - let mut impl_trait_proj = FxHashMap::)>>::default(); + let mut impl_trait_proj = FxHashMap::)>>::default(); let where_predicates = preds .predicates @@ -663,10 +664,11 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx if let Some(((_, trait_did, name), rhs)) = proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))) { - impl_trait_proj - .entry(param_idx) - .or_default() - .push((trait_did, name, rhs)); + impl_trait_proj.entry(param_idx).or_default().push(( + trait_did.into(), + name, + rhs, + )); } return None; @@ -685,7 +687,13 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx if let Some(proj) = impl_trait_proj.remove(&idx) { for (trait_did, name, rhs) in proj { let rhs = rhs.clean(cx); - simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs); + simplify::merge_bounds( + cx, + &mut bounds, + trait_did.expect_real(), + name, + &rhs, + ); } } } else { @@ -1175,7 +1183,8 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { if let Some(new_ty) = cx.ty_substs.get(&did).cloned() { return new_ty; } - if let Some(bounds) = cx.impl_trait_bounds.remove(&did.into()) { + if let Some(bounds) = cx.impl_trait_bounds.remove(&FakeDefId::new_real(did).into()) + { return ImplTrait(bounds); } } @@ -2006,7 +2015,7 @@ fn clean_extern_crate( vec![Item { name: Some(name), attrs: box attrs.clean(cx), - def_id: crate_def_id, + def_id: crate_def_id.into(), visibility: krate.vis.clean(cx), kind: box ExternCrateItem { src: orig_name }, cfg: attrs.cfg(cx.sess().diagnostic()), diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index a556fdba2f3f6..350742e8f2898 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1,6 +1,5 @@ -use std::cell::RefCell; +use std::cell::{Cell, RefCell}; use std::default::Default; -use std::fmt; use std::hash::{Hash, Hasher}; use std::iter::FromIterator; use std::lazy::SyncOnceCell as OnceCell; @@ -19,7 +18,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::thin_vec::ThinVec; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; -use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; +use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; use rustc_hir::{BodyId, Mutability}; use rustc_index::vec::IndexVec; @@ -49,7 +48,94 @@ use self::ItemKind::*; use self::SelfTy::*; use self::Type::*; -thread_local!(crate static MAX_DEF_IDX: RefCell> = Default::default()); +crate type FakeDefIdSet = FxHashSet; + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] +crate enum FakeDefId { + Real(DefId), + Fake(DefIndex, CrateNum), +} + +impl FakeDefId { + #[cfg(parallel_compiler)] + crate fn new_fake(crate: CrateNum) -> Self { + unimplemented!("") + } + + #[cfg(not(parallel_compiler))] + crate fn new_fake(krate: CrateNum) -> Self { + thread_local!(static FAKE_DEF_ID_COUNTER: Cell = Cell::new(0)); + let id = FAKE_DEF_ID_COUNTER.with(|id| { + let tmp = id.get(); + id.set(tmp + 1); + tmp + }); + Self::Fake(DefIndex::from(id), krate) + } + + crate fn new_real(id: DefId) -> Self { + Self::Real(id) + } + + #[inline] + crate fn is_local(self) -> bool { + match self { + FakeDefId::Real(id) => id.is_local(), + FakeDefId::Fake(_, krate) => krate == LOCAL_CRATE, + } + } + + #[inline] + crate fn as_local(self) -> Option { + match self { + FakeDefId::Real(id) => id.as_local(), + FakeDefId::Fake(idx, krate) => { + (krate == LOCAL_CRATE).then(|| LocalDefId { local_def_index: idx }) + } + } + } + + #[inline] + crate fn expect_local(self) -> LocalDefId { + self.as_local() + .unwrap_or_else(|| panic!("FakeDefId::expect_local: `{:?}` isn't local", self)) + } + + #[inline] + crate fn expect_real(self) -> rustc_hir::def_id::DefId { + self.as_real().unwrap_or_else(|| panic!("FakeDefId::expect_real: `{:?}` isn't real", self)) + } + + #[inline] + crate fn as_real(self) -> Option { + match self { + FakeDefId::Real(id) => Some(id), + FakeDefId::Fake(_, _) => None, + } + } + + #[inline] + crate fn krate(self) -> CrateNum { + match self { + FakeDefId::Real(id) => id.krate, + FakeDefId::Fake(_, krate) => krate, + } + } + + #[inline] + crate fn index(self) -> Option { + match self { + FakeDefId::Real(id) => Some(id.index), + FakeDefId::Fake(_, _) => None, + } + } +} + +impl From for FakeDefId { + fn from(id: DefId) -> Self { + Self::Real(id) + } +} #[derive(Clone, Debug)] crate struct Crate { @@ -261,7 +347,7 @@ impl 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)] crate struct Item { /// The name of this item. /// Optional because not every item has a name, e.g. impls. @@ -271,7 +357,7 @@ crate struct Item { /// Information about this item that is specific to what kind of item it is. /// E.g., struct vs enum vs function. crate kind: Box, - crate def_id: DefId, + crate def_id: FakeDefId, crate cfg: Option>, } @@ -280,21 +366,6 @@ crate struct Item { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] rustc_data_structures::static_assert_size!(Item, 48); -impl fmt::Debug for Item { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - let def_id: &dyn fmt::Debug = if self.is_fake() { &"**FAKE**" } else { &self.def_id }; - - fmt.debug_struct("Item") - .field("name", &self.name) - .field("attrs", &self.attrs) - .field("kind", &self.kind) - .field("visibility", &self.visibility) - .field("def_id", def_id) - .field("cfg", &self.cfg) - .finish() - } -} - crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span { Span::from_rustc_span(def_id.as_local().map_or_else( || tcx.def_span(def_id), @@ -307,19 +378,19 @@ crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span { impl Item { crate fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx Stability> { - if self.is_fake() { None } else { tcx.lookup_stability(self.def_id) } + if self.is_fake() { None } else { tcx.lookup_stability(self.def_id.expect_real()) } } crate fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ConstStability> { - if self.is_fake() { None } else { tcx.lookup_const_stability(self.def_id) } + if self.is_fake() { None } else { tcx.lookup_const_stability(self.def_id.expect_real()) } } crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option { - if self.is_fake() { None } else { tcx.lookup_deprecation(self.def_id) } + if self.is_fake() { None } else { tcx.lookup_deprecation(self.def_id.expect_real()) } } crate fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { - if self.is_fake() { false } else { tcx.get_attrs(self.def_id).inner_docs() } + if self.is_fake() { false } else { tcx.get_attrs(self.def_id.expect_real()).inner_docs() } } crate fn span(&self, tcx: TyCtxt<'_>) -> Span { @@ -334,7 +405,7 @@ impl Item { } else if self.is_fake() { Span::dummy() } else { - rustc_span(self.def_id, tcx) + rustc_span(self.def_id.expect_real(), tcx) } } @@ -388,7 +459,7 @@ impl Item { debug!("name={:?}, def_id={:?}", name, def_id); Item { - def_id, + def_id: def_id.into(), kind: box kind, name, attrs, @@ -412,9 +483,9 @@ impl Item { .map_or(&[][..], |v| v.as_slice()) .iter() .filter_map(|ItemLink { link: s, link_text, did, ref fragment }| { - match *did { + match did { Some(did) => { - if let Some((mut href, ..)) = href(did, cx) { + if let Some((mut href, ..)) = href(did.expect_real(), cx) { if let Some(ref fragment) = *fragment { href.push('#'); href.push_str(fragment); @@ -433,8 +504,8 @@ impl Item { None => { let relative_to = &cx.current; if let Some(ref fragment) = *fragment { - let url = match cx.cache().extern_locations.get(&self.def_id.krate) { - Some(ExternalLocation::Local) => { + let url = match cx.cache().extern_locations.get(&self.def_id.krate()) { + Some(&ExternalLocation::Local) => { if relative_to[0] == "std" { let depth = relative_to.len() - 1; "../".repeat(depth) @@ -473,7 +544,7 @@ impl Item { } crate fn is_crate(&self) -> bool { - self.is_mod() && self.def_id.index == CRATE_DEF_INDEX + self.is_mod() && self.def_id.as_real().map_or(false, |did| did.index == CRATE_DEF_INDEX) } crate fn is_mod(&self) -> bool { @@ -586,13 +657,8 @@ impl Item { } } - /// See the documentation for [`next_def_id()`]. - /// - /// [`next_def_id()`]: DocContext::next_def_id() crate fn is_fake(&self) -> bool { - MAX_DEF_IDX.with(|m| { - m.borrow().get(&self.def_id.krate).map(|&idx| idx <= self.def_id.index).unwrap_or(false) - }) + matches!(self.def_id, FakeDefId::Fake(_, _)) } } @@ -911,7 +977,7 @@ crate struct ItemLink { /// This may not be the same as `link` if there was a disambiguator /// in an intra-doc link (e.g. \[`fn@f`\]) pub(crate) link_text: String, - pub(crate) did: Option, + pub(crate) did: Option, /// The url fragment to append to the link pub(crate) fragment: Option, } @@ -1032,7 +1098,7 @@ impl Attributes { } } - let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| { + let clean_attr = |(attr, parent_module): (&ast::Attribute, Option)| { if let Some(value) = attr.doc_str() { trace!("got doc_str={:?}", value); let value = beautify_doc_string(value); @@ -1652,7 +1718,7 @@ impl Type { impl Type { fn inner_def_id(&self, cache: Option<&Cache>) -> Option { let t: PrimitiveType = match *self { - ResolvedPath { did, .. } => return Some(did), + ResolvedPath { did, .. } => return Some(did.into()), Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()), BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference, BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache), diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 7df8b442e5acc..eda7ebfaab980 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -45,9 +45,9 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { // `#[doc(masked)]` to the injected `extern crate` because it's unstable. if it.is_extern_crate() && (it.attrs.has_doc_flag(sym::masked) - || cx.tcx.is_compiler_builtins(it.def_id.krate)) + || cx.tcx.is_compiler_builtins(it.def_id.krate())) { - cx.cache.masked_crates.insert(it.def_id.krate); + cx.cache.masked_crates.insert(it.def_id.krate()); } } } @@ -490,8 +490,6 @@ where } /// Find the nearest parent module of a [`DefId`]. -/// -/// **Panics if the item it belongs to [is fake][Item::is_fake].** crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if def_id.is_top_level_module() { // The crate root has no parent. Use it as the root instead. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 212aac0e5b43c..b0d163763b4bd 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::Res; -use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::HirId; use rustc_hir::{ intravisit::{self, NestedVisitorMap, Visitor}, @@ -26,13 +26,11 @@ use rustc_span::symbol::sym; use rustc_span::Span; use std::cell::RefCell; -use std::collections::hash_map::Entry; use std::mem; use std::rc::Rc; -use crate::clean; use crate::clean::inline::build_external_trait; -use crate::clean::{TraitWithExtraInfo, MAX_DEF_IDX}; +use crate::clean::{self, FakeDefId, TraitWithExtraInfo}; use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions}; use crate::formats::cache::Cache; use crate::passes::{self, Condition::*, ConditionalPass}; @@ -66,7 +64,6 @@ crate struct DocContext<'tcx> { crate ct_substs: FxHashMap, /// Table synthetic type parameter for `impl Trait` in argument position -> bounds crate impl_trait_bounds: FxHashMap>, - crate fake_def_ids: FxHashMap, /// Auto-trait or blanket impls processed so far, as `(self_ty, trait_def_id)`. // FIXME(eddyb) make this a `ty::TraitRef<'tcx>` set. crate generated_synthetics: FxHashSet<(Ty<'tcx>, DefId)>, @@ -81,7 +78,7 @@ crate struct DocContext<'tcx> { /// This same cache is used throughout rustdoc, including in [`crate::html::render`]. crate cache: Cache, /// Used by [`clean::inline`] to tell if an item has already been inlined. - crate inlined: FxHashSet, + crate inlined: FxHashSet, /// Used by `calculate_doc_coverage`. crate output_format: OutputFormat, } @@ -129,54 +126,14 @@ impl<'tcx> DocContext<'tcx> { r } - /// 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 } - } - /// Like `hir().local_def_id_to_hir_id()`, but skips calling it on fake DefIds. /// (This avoids a slice-index-out-of-bounds panic.) - crate fn as_local_hir_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - if MAX_DEF_IDX.with(|m| { - m.borrow().get(&def_id.krate).map(|&idx| idx <= def_id.index).unwrap_or(false) - }) { - None - } else { - def_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)) + crate fn as_local_hir_id(tcx: TyCtxt<'_>, def_id: FakeDefId) -> Option { + match def_id { + FakeDefId::Real(real_id) => { + real_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)) + } + FakeDefId::Fake(_, _) => None, } } } @@ -419,7 +376,6 @@ crate fn run_global_ctxt( lt_substs: Default::default(), ct_substs: Default::default(), impl_trait_bounds: Default::default(), - fake_def_ids: Default::default(), generated_synthetics: Default::default(), auto_traits: tcx .all_traits(LOCAL_CRATE) @@ -630,12 +586,12 @@ impl<'tcx> Visitor<'tcx> for EmitIgnoredResolutionErrors<'tcx> { /// for `impl Trait` in argument position. #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] crate enum ImplTraitParam { - DefId(DefId), + DefId(FakeDefId), ParamIndex(u32), } -impl From for ImplTraitParam { - fn from(did: DefId) -> Self { +impl From for ImplTraitParam { + fn from(did: FakeDefId) -> Self { ImplTraitParam::DefId(did) } } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index b6b76a96e7f96..50496f320096c 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -8,7 +8,7 @@ use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; -use crate::clean::{self, GetDefId}; +use crate::clean::{self, FakeDefId, GetDefId}; use crate::fold::DocFolder; use crate::formats::item_type::ItemType; use crate::formats::Impl; @@ -67,7 +67,7 @@ crate struct Cache { /// When rendering traits, it's often useful to be able to list all /// implementors of the trait, and this mapping is exactly, that: a mapping /// of trait ids to the list of known implementors of the trait - crate implementors: FxHashMap>, + crate implementors: FxHashMap>, /// Cache of where external crate documentation can be found. crate extern_locations: FxHashMap, @@ -122,7 +122,7 @@ crate struct Cache { /// All intra-doc links resolved so far. /// /// Links are indexed by the DefId of the item they document. - crate intra_doc_links: BTreeMap>, + crate intra_doc_links: BTreeMap>, } /// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`. @@ -205,7 +205,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // If the impl is from a masked crate or references something from a // masked crate then remove it completely. if let clean::ImplItem(ref i) = *item.kind { - if self.cache.masked_crates.contains(&item.def_id.krate) + if self.cache.masked_crates.contains(&item.def_id.krate()) || i.trait_.def_id().map_or(false, |d| self.cache.masked_crates.contains(&d.krate)) || i.for_.def_id().map_or(false, |d| self.cache.masked_crates.contains(&d.krate)) { @@ -216,9 +216,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // Propagate a trait method's documentation to all implementors of the // trait. if let clean::TraitItem(ref t) = *item.kind { - self.cache.traits.entry(item.def_id).or_insert_with(|| clean::TraitWithExtraInfo { - trait_: t.clone(), - is_notable: item.attrs.has_doc_flag(sym::notable_trait), + self.cache.traits.entry(item.def_id.expect_real()).or_insert_with(|| { + clean::TraitWithExtraInfo { + trait_: t.clone(), + is_notable: item.attrs.has_doc_flag(sym::notable_trait), + } }); } @@ -228,7 +230,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { if i.blanket_impl.is_none() { self.cache .implementors - .entry(did) + .entry(did.into()) .or_default() .push(Impl { impl_item: item.clone() }); } @@ -289,7 +291,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // A crate has a module at its root, containing all items, // which should not be indexed. The crate-item itself is // inserted later on when serializing the search-index. - if item.def_id.index != CRATE_DEF_INDEX { + if item.def_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) { self.cache.search_index.push(IndexItem { ty: item.type_(), name: s.to_string(), @@ -297,7 +299,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { desc: item .doc_value() .map_or_else(String::new, |x| short_markdown_summary(&x.as_str())), - parent, + parent: parent.map(FakeDefId::new_real), parent_idx: None, search_type: get_index_search_type(&item, &self.empty_cache, self.tcx), aliases: item.attrs.get_doc_aliases(), @@ -346,17 +348,20 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // `public_items` map, so we can skip inserting into the // paths map if there was already an entry present and we're // not a public item. - if !self.cache.paths.contains_key(&item.def_id) - || self.cache.access_levels.is_public(item.def_id) + if !self.cache.paths.contains_key(&item.def_id.expect_real()) + || self.cache.access_levels.is_public(item.def_id.expect_real()) { - self.cache - .paths - .insert(item.def_id, (self.cache.stack.clone(), item.type_())); + self.cache.paths.insert( + item.def_id.expect_real(), + (self.cache.stack.clone(), item.type_()), + ); } } } clean::PrimitiveItem(..) => { - self.cache.paths.insert(item.def_id, (self.cache.stack.clone(), item.type_())); + self.cache + .paths + .insert(item.def_id.expect_real(), (self.cache.stack.clone(), item.type_())); } clean::ExternCrateItem { .. } @@ -386,7 +391,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { | clean::StructItem(..) | clean::UnionItem(..) | clean::VariantItem(..) => { - self.cache.parent_stack.push(item.def_id); + self.cache.parent_stack.push(item.def_id.expect_real()); self.cache.parent_is_trait_impl = false; true } diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs index 1ce6572bbed04..6060b0560cf3c 100644 --- a/src/librustdoc/formats/mod.rs +++ b/src/librustdoc/formats/mod.rs @@ -2,9 +2,9 @@ crate mod cache; crate mod item_type; crate mod renderer; -crate use renderer::{run_format, FormatRenderer}; +use rustc_hir::def_id::DefId; -use rustc_span::def_id::DefId; +crate use renderer::{run_format, FormatRenderer}; use crate::clean; use crate::clean::types::GetDefId; diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f211a5acf5ea5..fa57c9bda74da 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -12,11 +12,14 @@ use std::iter; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; +use rustc_hir::def_id::DefId; use rustc_middle::ty::TyCtxt; -use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc_span::def_id::CRATE_DEF_INDEX; use rustc_target::spec::abi::Abi; -use crate::clean::{self, utils::find_nearest_parent_module, ExternalCrate, PrimitiveType}; +use crate::clean::{ + self, utils::find_nearest_parent_module, ExternalCrate, FakeDefId, PrimitiveType, +}; use crate::formats::item_type::ItemType; use crate::html::escape::Escape; use crate::html::render::cache::ExternalLocation; @@ -637,7 +640,7 @@ crate fn anchor<'a, 'cx: 'a>( text: &'a str, cx: &'cx Context<'_>, ) -> impl fmt::Display + 'a { - let parts = href(did, cx); + let parts = href(did.into(), cx); display_fn(move |f| { if let Some((url, short_ty, fqp)) = parts { write!( @@ -865,7 +868,7 @@ fn fmt_type<'cx>( // everything comes in as a fully resolved QPath (hard to // look at). box clean::ResolvedPath { did, ref param_names, .. } => { - match href(did, cx) { + match href(did.into(), cx) { Some((ref url, _, ref path)) if !f.alternate() => { write!( f, @@ -1143,7 +1146,7 @@ impl clean::FnDecl { impl clean::Visibility { crate fn print_with_space<'a, 'tcx: 'a>( self, - item_did: DefId, + item_did: FakeDefId, cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { let to_print = match self { @@ -1153,7 +1156,7 @@ impl clean::Visibility { // FIXME(camelid): This may not work correctly if `item_did` is a module. // However, rustdoc currently never displays a module's // visibility, so it shouldn't matter. - let parent_module = find_nearest_parent_module(cx.tcx(), item_did); + let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_real()); if vis_did.index == CRATE_DEF_INDEX { "pub(crate) ".to_owned() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 27a8065afb6d2..57520a1a1fb46 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -7,7 +7,7 @@ use serde::ser::{Serialize, SerializeStruct, Serializer}; use crate::clean; use crate::clean::types::{ - FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, WherePredicate, + FakeDefId, FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, WherePredicate, }; use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; @@ -39,7 +39,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< name: item.name.unwrap().to_string(), path: fqp[..fqp.len() - 1].join("::"), desc: item.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)), - parent: Some(did), + parent: Some(did.into()), parent_idx: None, search_type: get_index_search_type(&item, cache, tcx), aliases: item.attrs.get_doc_aliases(), @@ -82,7 +82,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< defid_to_pathid.insert(defid, pathid); lastpathid += 1; - if let Some(&(ref fqp, short)) = paths.get(&defid) { + if let Some(&(ref fqp, short)) = paths.get(&defid.expect_real()) { crate_paths.push((short, fqp.last().unwrap().clone())); Some(pathid) } else { @@ -214,7 +214,7 @@ crate fn get_index_search_type<'tcx>( fn get_index_type(clean_type: &clean::Type, cache: &Cache) -> RenderType { RenderType { - ty: clean_type.def_id_full(cache), + ty: clean_type.def_id_full(cache).map(FakeDefId::new_real), idx: None, name: get_index_type_name(clean_type, true).map(|s| s.as_str().to_ascii_lowercase()), generics: get_generics(clean_type, cache), @@ -256,7 +256,7 @@ fn get_generics(clean_type: &clean::Type, cache: &Cache) -> Option> .filter_map(|t| { get_index_type_name(t, false).map(|name| Generic { name: name.as_str().to_ascii_lowercase(), - defid: t.def_id_full(cache), + defid: t.def_id_full(cache).map(FakeDefId::new_real), idx: None, }) }) diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 293c0a40fa799..2f3f87215c3a1 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -18,7 +18,8 @@ use super::print_item::{full_path, item_path, print_item}; use super::write_shared::write_shared; use super::{print_sidebar, settings, AllTypes, NameDoc, StylePath, BASIC_KEYWORDS}; -use crate::clean::{self, ExternalCrate}; +use crate::clean; +use crate::clean::ExternalCrate; use crate::config::RenderOptions; use crate::docfs::{DocFS, PathError}; use crate::error::Error; @@ -218,7 +219,7 @@ impl<'tcx> Context<'tcx> { &self.shared.style_files, ) } else { - if let Some(&(ref names, ty)) = self.cache.paths.get(&it.def_id) { + if let Some(&(ref names, ty)) = self.cache.paths.get(&it.def_id.expect_real()) { let mut path = String::new(); for name in &names[..names.len() - 1] { path.push_str(name); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1271b54debd16..ea57831c0e5de 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -54,7 +54,7 @@ use rustc_span::symbol::{kw, sym, Symbol}; use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; -use crate::clean::{self, GetDefId, RenderedLink, SelfTy}; +use crate::clean::{self, FakeDefId, GetDefId, RenderedLink, SelfTy}; use crate::docfs::PathError; use crate::error::Error; use crate::formats::cache::Cache; @@ -87,7 +87,7 @@ crate struct IndexItem { crate name: String, crate path: String, crate desc: String, - crate parent: Option, + crate parent: Option, crate parent_idx: Option, crate search_type: Option, crate aliases: Box<[String]>, @@ -96,7 +96,7 @@ crate struct IndexItem { /// A type used for the search index. #[derive(Debug)] crate struct RenderType { - ty: Option, + ty: Option, idx: Option, name: Option, generics: Option>, @@ -128,7 +128,7 @@ impl Serialize for RenderType { #[derive(Debug)] crate struct Generic { name: String, - defid: Option, + defid: Option, idx: Option, } @@ -709,7 +709,7 @@ fn render_impls( .map(|i| { let did = i.trait_did_full(cache).unwrap(); let provided_trait_methods = i.inner_impl().provided_trait_methods(tcx); - let assoc_link = AssocItemLink::GotoSource(did, &provided_trait_methods); + let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods); let mut buffer = if w.is_for_html() { Buffer::html() } else { Buffer::new() }; render_impl( &mut buffer, @@ -747,7 +747,7 @@ fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id), AssocItemLink::Anchor(None) => anchor, AssocItemLink::GotoSource(did, _) => { - href(did, cx).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor) + href(did.expect_real(), cx).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor) } } } @@ -855,7 +855,7 @@ fn render_assoc_item( ItemType::TyMethod }; - href(did, cx) + href(did.expect_real(), cx) .map(|p| format!("{}#{}.{}", p.0, ty, name)) .unwrap_or_else(|| format!("#{}.{}", ty, name)) } @@ -979,7 +979,7 @@ fn render_attributes_in_code(w: &mut Buffer, it: &clean::Item) { #[derive(Copy, Clone)] enum AssocItemLink<'a> { Anchor(Option<&'a str>), - GotoSource(DefId, &'a FxHashSet), + GotoSource(FakeDefId, &'a FxHashSet), } impl<'a> AssocItemLink<'a> { @@ -1217,7 +1217,7 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String { it, &[], Some(&tydef.type_), - AssocItemLink::GotoSource(t_did, &FxHashSet::default()), + AssocItemLink::GotoSource(t_did.into(), &FxHashSet::default()), "", cx, ); @@ -1476,7 +1476,7 @@ fn render_impl( } let did = i.trait_.as_ref().unwrap().def_id_full(cx.cache()).unwrap(); let provided_methods = i.provided_trait_methods(cx.tcx()); - let assoc_link = AssocItemLink::GotoSource(did, &provided_methods); + let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods); doc_impl_item( boring, @@ -1810,7 +1810,8 @@ fn small_url_encode(s: String) -> String { } fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) { - if let Some(v) = cx.cache.impls.get(&it.def_id) { + let did = it.def_id.expect_real(); + if let Some(v) = cx.cache.impls.get(&did) { let mut used_links = FxHashSet::default(); let cache = cx.cache(); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 1bf726dd31a46..70b5458ece894 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -270,14 +270,18 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl w, "{}extern crate {} as {};", myitem.visibility.print_with_space(myitem.def_id, cx), - anchor(myitem.def_id, &*src.as_str(), cx), + anchor(myitem.def_id.expect_real(), &*src.as_str(), cx), myitem.name.as_ref().unwrap(), ), None => write!( w, "{}extern crate {};", myitem.visibility.print_with_space(myitem.def_id, cx), - anchor(myitem.def_id, &*myitem.name.as_ref().unwrap().as_str(), cx), + anchor( + myitem.def_id.expect_real(), + &*myitem.name.as_ref().unwrap().as_str(), + cx + ), ), } w.write_str(""); @@ -290,7 +294,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl // Just need an item with the correct def_id and attrs let import_item = clean::Item { - def_id: import_def_id, + def_id: import_def_id.into(), attrs: import_attrs, cfg: ast_attrs.cfg(cx.tcx().sess.diagnostic()), ..myitem.clone() @@ -629,7 +633,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All); if let Some(implementors) = cx.cache.implementors.get(&it.def_id) { // The DefId is for the first Type found with that name. The bool is @@ -752,7 +756,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra path = if it.def_id.is_local() { cx.current.join("/") } else { - let (ref path, _) = cx.cache.external_paths[&it.def_id]; + let (ref path, _) = cx.cache.external_paths[&it.def_id.expect_real()]; path[..path.len() - 1].join("/") }, ty = it.type_(), @@ -778,7 +782,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) } fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) { @@ -799,7 +803,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean: // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) } fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { @@ -820,7 +824,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::T // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) } fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Union) { @@ -866,7 +870,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni document(w, cx, field, Some(it)); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) } fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) { @@ -1000,7 +1004,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum render_stability_since(w, variant, it, cx.tcx()); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) } fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) { @@ -1049,7 +1053,7 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { document(w, cx, it, None); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) } fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) { @@ -1137,7 +1141,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St } } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) } fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) { @@ -1166,7 +1170,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { document(w, cx, it, None); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All) } fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 8e10c696df05d..c493801d9907f 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -464,6 +464,8 @@ pub(super) fn write_shared( // Update the list of all implementors for traits let dst = cx.dst.join("implementors"); for (&did, imps) in &cx.cache.implementors { + let did = did.expect_real(); + // Private modules can leak through to this phase of rustdoc, which // could contain implementations for otherwise private types. In some // rare cases we could find an implementation for an item which wasn't @@ -496,7 +498,7 @@ pub(super) fn write_shared( // // If the implementation is from another crate then that crate // should add it. - if imp.impl_item.def_id.krate == did.krate || !imp.impl_item.def_id.is_local() { + if imp.impl_item.def_id.krate() == did.krate || !imp.impl_item.def_id.is_local() { None } else { Some(Implementor { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 8ca6342462fc4..e3f1c6b1e2dc4 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -9,13 +9,14 @@ use std::convert::From; use rustc_ast::ast; use rustc_hir::def::CtorKind; use rustc_middle::ty::TyCtxt; -use rustc_span::def_id::{DefId, CRATE_DEF_INDEX}; +use rustc_span::def_id::CRATE_DEF_INDEX; use rustc_span::Pos; use rustdoc_json_types::*; use crate::clean; use crate::clean::utils::print_const_expr; +use crate::clean::FakeDefId; use crate::formats::item_type::ItemType; use crate::json::JsonRenderer; use std::collections::HashSet; @@ -48,7 +49,7 @@ impl JsonRenderer<'_> { }; Some(Item { id: from_def_id(def_id), - crate_id: def_id.krate.as_u32(), + crate_id: def_id.krate().as_u32(), name: name.map(|sym| sym.to_string()), span: self.convert_span(span), visibility: self.convert_visibility(visibility), @@ -87,7 +88,7 @@ impl JsonRenderer<'_> { Inherited => Visibility::Default, Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate, Restricted(did) => Visibility::Restricted { - parent: from_def_id(did), + parent: from_def_id(did.into()), path: self.tcx.def_path(did).to_string_no_crate_verbose(), }, } @@ -171,8 +172,13 @@ impl FromWithTcx for TypeBindingKind { } } -crate fn from_def_id(did: DefId) -> Id { - Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index))) +crate fn from_def_id(did: FakeDefId) -> Id { + match did { + FakeDefId::Real(did) => Id(format!("{}:{}", did.krate.as_u32(), u32::from(did.index))), + // We need to differentiate real and fake ids, because the indices might overlap for fake + // and real DefId's, which would cause two different Id's treated as they were the same. + FakeDefId::Fake(idx, krate) => Id(format!("F{}:{}", krate.as_u32(), u32::from(idx))), + } } fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum { @@ -368,7 +374,7 @@ impl FromWithTcx for Type { match ty { ResolvedPath { path, param_names, did, is_generic: _ } => Type::ResolvedPath { name: path.whole_name(), - id: from_def_id(did), + id: from_def_id(did.into()), args: path.segments.last().map(|args| Box::new(args.clone().args.into_tcx(tcx))), param_names: param_names .map(|v| v.into_iter().map(|x| x.into_tcx(tcx)).collect()) @@ -540,13 +546,13 @@ impl FromWithTcx for Import { Simple(s) => Import { source: import.source.path.whole_name(), name: s.to_string(), - id: import.source.did.map(from_def_id), + id: import.source.did.map(FakeDefId::from).map(from_def_id), glob: false, }, Glob => Import { source: import.source.path.whole_name(), name: import.source.path.last_name().to_string(), - id: import.source.did.map(from_def_id), + id: import.source.did.map(FakeDefId::from).map(from_def_id), glob: true, }, } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index ae4d1be3ec2b8..d56acad60c00f 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -17,7 +17,8 @@ use rustc_session::Session; use rustdoc_json_types as types; -use crate::clean::{self, ExternalCrate}; +use crate::clean; +use crate::clean::{ExternalCrate, FakeDefId}; use crate::config::RenderOptions; use crate::error::Error; use crate::formats::cache::Cache; @@ -41,7 +42,7 @@ impl JsonRenderer<'tcx> { self.tcx.sess } - fn get_trait_implementors(&mut self, id: rustc_span::def_id::DefId) -> Vec { + fn get_trait_implementors(&mut self, id: FakeDefId) -> Vec { Rc::clone(&self.cache) .implementors .get(&id) @@ -58,10 +59,10 @@ impl JsonRenderer<'tcx> { .unwrap_or_default() } - fn get_impls(&mut self, id: rustc_span::def_id::DefId) -> Vec { + fn get_impls(&mut self, id: FakeDefId) -> Vec { Rc::clone(&self.cache) .impls - .get(&id) + .get(&id.expect_real()) .map(|impls| { impls .iter() @@ -89,9 +90,9 @@ impl JsonRenderer<'tcx> { let trait_item = &trait_item.trait_; trait_item.items.clone().into_iter().for_each(|i| self.item(i).unwrap()); Some(( - from_def_id(id), + from_def_id(id.into()), types::Item { - id: from_def_id(id), + id: from_def_id(id.into()), crate_id: id.krate.as_u32(), name: self .cache @@ -205,7 +206,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { .chain(self.cache.external_paths.clone().into_iter()) .map(|(k, (path, kind))| { ( - from_def_id(k), + from_def_id(k.into()), types::ItemSummary { crate_id: k.krate.as_u32(), path, diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index 68a66806e0476..8d07cde51880c 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -111,7 +111,11 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> { fn fold_item(&mut self, item: clean::Item) -> Option { if let Some(dox) = &item.attrs.collapsed_doc_value() { let sp = item.attr_span(self.cx.tcx); - let extra = crate::html::markdown::ExtraInfo::new_did(self.cx.tcx, item.def_id, sp); + let extra = crate::html::markdown::ExtraInfo::new_did( + self.cx.tcx, + item.def_id.expect_real(), + sp, + ); for code_block in markdown::rust_code_blocks(&dox, &extra) { self.check_rust_syntax(&item, &dox, code_block); } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index f1064756fdde7..c5fb54e52c7c4 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -30,7 +30,9 @@ use std::convert::{TryFrom, TryInto}; use std::mem; use std::ops::Range; -use crate::clean::{self, utils::find_nearest_parent_module, Crate, Item, ItemLink, PrimitiveType}; +use crate::clean::{ + self, utils::find_nearest_parent_module, Crate, FakeDefId, Item, ItemLink, PrimitiveType, +}; use crate::core::DocContext; use crate::fold::DocFolder; use crate::html::markdown::{markdown_links, MarkdownLink}; @@ -246,7 +248,7 @@ enum AnchorFailure { #[derive(Clone, Debug, Hash, PartialEq, Eq)] struct ResolutionInfo { - module_id: DefId, + module_id: FakeDefId, dis: Option, path_str: String, extra_fragment: Option, @@ -272,7 +274,7 @@ struct LinkCollector<'a, 'tcx> { /// /// The last module will be used if the parent scope of the current item is /// unknown. - mod_ids: Vec, + mod_ids: Vec, /// This is used to store the kind of associated items, /// because `clean` and the disambiguator code expect them to be different. /// See the code for associated items on inherent impls for details. @@ -296,7 +298,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ) -> Result<(Res, Option), ErrorKind<'path>> { let tcx = self.cx.tcx; let no_res = || ResolutionFailure::NotResolved { - module_id, + module_id: module_id.into(), partial_res: None, unresolved: path_str.into(), }; @@ -524,7 +526,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // but the disambiguator logic expects the associated item. // Store the kind in a side channel so that only the disambiguator logic looks at it. if let Some((kind, id)) = side_channel { - self.kind_side_channel.set(Some((kind, id))); + self.kind_side_channel.set(Some((kind, id.into()))); } Ok((res, Some(fragment))) }; @@ -795,7 +797,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { let parent_node = if item.is_fake() { None } else { - find_nearest_parent_module(self.cx.tcx, item.def_id) + find_nearest_parent_module(self.cx.tcx, item.def_id.expect_real()) }; if parent_node.is_some() { @@ -807,31 +809,34 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { let self_id = if item.is_fake() { None // Checking if the item is a field in an enum variant - } else if (matches!(self.cx.tcx.def_kind(item.def_id), DefKind::Field) + } else if (matches!(self.cx.tcx.def_kind(item.def_id.expect_real()), DefKind::Field) && matches!( - self.cx.tcx.def_kind(self.cx.tcx.parent(item.def_id).unwrap()), + self.cx.tcx.def_kind(self.cx.tcx.parent(item.def_id.expect_real()).unwrap()), DefKind::Variant )) { - self.cx.tcx.parent(item.def_id).and_then(|item_id| self.cx.tcx.parent(item_id)) + self.cx + .tcx + .parent(item.def_id.expect_real()) + .and_then(|item_id| self.cx.tcx.parent(item_id)) } else if matches!( - self.cx.tcx.def_kind(item.def_id), + self.cx.tcx.def_kind(item.def_id.expect_real()), DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy | DefKind::Variant | DefKind::Field ) { - self.cx.tcx.parent(item.def_id) + self.cx.tcx.parent(item.def_id.expect_real()) // HACK(jynelson): `clean` marks associated types as `TypedefItem`, not as `AssocTypeItem`. // Fixing this breaks `fn render_deref_methods`. // As a workaround, see if the parent of the item is an `impl`; if so this must be an associated item, // regardless of what rustdoc wants to call it. - } else if let Some(parent) = self.cx.tcx.parent(item.def_id) { + } else if let Some(parent) = self.cx.tcx.parent(item.def_id.expect_real()) { let parent_kind = self.cx.tcx.def_kind(parent); - Some(if parent_kind == DefKind::Impl { parent } else { item.def_id }) + Some(if parent_kind == DefKind::Impl { parent } else { item.def_id.expect_real() }) } else { - Some(item.def_id) + Some(item.def_id.expect_real()) }; // FIXME(jynelson): this shouldn't go through stringification, rustdoc should just use the DefId directly @@ -869,7 +874,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { let (krate, parent_node) = if let Some(id) = parent_module { (id.krate, Some(id)) } else { - (item.def_id.krate, parent_node) + (item.def_id.krate(), parent_node) }; // NOTE: if there are links that start in one crate and end in another, this will not resolve them. // This is a degenerate case and it's not supported by rustdoc. @@ -1065,8 +1070,11 @@ impl LinkCollector<'_, '_> { // we've already pushed this node onto the resolution stack but // for outer comments we explicitly try and resolve against the // parent_node first. - let base_node = - if item.is_mod() && inner_docs { self.mod_ids.last().copied() } else { parent_node }; + let base_node = if item.is_mod() && inner_docs { + self.mod_ids.last().copied() + } else { + parent_node.map(|id| FakeDefId::new_real(id)) + }; let mut module_id = if let Some(id) = base_node { id @@ -1111,7 +1119,7 @@ impl LinkCollector<'_, '_> { resolved_self = format!("self::{}", &path_str["crate::".len()..]); path_str = &resolved_self; } - module_id = DefId { krate, index: CRATE_DEF_INDEX }; + module_id = FakeDefId::new_real(DefId { krate, index: CRATE_DEF_INDEX }); } let (mut res, mut fragment) = self.resolve_with_disambiguator_cached( @@ -1172,8 +1180,8 @@ impl LinkCollector<'_, '_> { report_diagnostic(self.cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, &diag_info, callback); }; - let verify = |kind: DefKind, id: DefId| { - let (kind, id) = self.kind_side_channel.take().unwrap_or((kind, id)); + let verify = |kind: DefKind, id: FakeDefId| { + let (kind, id) = self.kind_side_channel.take().unwrap_or((kind, id.expect_real())); debug!("intra-doc link to {} resolved to {:?} (id: {:?})", path_str, res, id); // Disallow e.g. linking to enums with `struct@` @@ -1227,7 +1235,7 @@ impl LinkCollector<'_, '_> { // doesn't allow statements like `use str::trim;`, making this a (hopefully) // valid omission. See https://github.com/rust-lang/rust/pull/80660#discussion_r551585677 // for discussion on the matter. - verify(kind, id)?; + verify(kind, id.into())?; // FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether. // However I'm not sure how to check that across crates. @@ -1265,9 +1273,9 @@ impl LinkCollector<'_, '_> { Some(ItemLink { link: ori_link.link, link_text, did: None, fragment }) } Res::Def(kind, id) => { - verify(kind, id)?; + verify(kind, id.into())?; let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id)); - Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment }) + Some(ItemLink { link: ori_link.link, link_text, did: Some(id.into()), fragment }) } } } @@ -1333,7 +1341,7 @@ impl LinkCollector<'_, '_> { match disambiguator.map(Disambiguator::ns) { Some(expected_ns @ (ValueNS | TypeNS)) => { - match self.resolve(path_str, expected_ns, base_node, extra_fragment) { + match self.resolve(path_str, expected_ns, base_node.expect_real(), extra_fragment) { Ok(res) => Some(res), Err(ErrorKind::Resolve(box mut kind)) => { // We only looked in one namespace. Try to give a better error if possible. @@ -1342,9 +1350,12 @@ impl LinkCollector<'_, '_> { // FIXME: really it should be `resolution_failure` that does this, not `resolve_with_disambiguator` // See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach for &new_ns in &[other_ns, MacroNS] { - if let Some(res) = - self.check_full_res(new_ns, path_str, base_node, extra_fragment) - { + if let Some(res) = self.check_full_res( + new_ns, + path_str, + base_node.expect_real(), + extra_fragment, + ) { kind = ResolutionFailure::WrongNamespace { res, expected_ns }; break; } @@ -1366,9 +1377,14 @@ impl LinkCollector<'_, '_> { // Try everything! let mut candidates = PerNS { macro_ns: self - .resolve_macro(path_str, base_node) + .resolve_macro(path_str, base_node.expect_real()) .map(|res| (res, extra_fragment.clone())), - type_ns: match self.resolve(path_str, TypeNS, base_node, extra_fragment) { + type_ns: match self.resolve( + path_str, + TypeNS, + base_node.expect_real(), + extra_fragment, + ) { Ok(res) => { debug!("got res in TypeNS: {:?}", res); Ok(res) @@ -1379,7 +1395,12 @@ impl LinkCollector<'_, '_> { } Err(ErrorKind::Resolve(box kind)) => Err(kind), }, - value_ns: match self.resolve(path_str, ValueNS, base_node, extra_fragment) { + value_ns: match self.resolve( + path_str, + ValueNS, + base_node.expect_real(), + extra_fragment, + ) { Ok(res) => Ok(res), Err(ErrorKind::AnchorFailure(msg)) => { anchor_failure(self.cx, diag, msg); @@ -1421,7 +1442,7 @@ impl LinkCollector<'_, '_> { } if len == 1 { - Some(candidates.into_iter().filter_map(|res| res.ok()).next().unwrap()) + Some(candidates.into_iter().find_map(|res| res.ok()).unwrap()) } else if len == 2 && is_derive_trait_collision(&candidates) { Some(candidates.type_ns.unwrap()) } else { @@ -1435,14 +1456,17 @@ impl LinkCollector<'_, '_> { } } Some(MacroNS) => { - match self.resolve_macro(path_str, base_node) { + match self.resolve_macro(path_str, base_node.expect_real()) { Ok(res) => Some((res, extra_fragment.clone())), Err(mut kind) => { // `resolve_macro` only looks in the macro namespace. Try to give a better error if possible. for &ns in &[TypeNS, ValueNS] { - if let Some(res) = - self.check_full_res(ns, path_str, base_node, extra_fragment) - { + if let Some(res) = self.check_full_res( + ns, + path_str, + base_node.expect_real(), + extra_fragment, + ) { kind = ResolutionFailure::WrongNamespace { res, expected_ns: MacroNS }; break; @@ -1795,7 +1819,7 @@ fn resolution_failure( name = start; for &ns in &[TypeNS, ValueNS, MacroNS] { if let Some(res) = - collector.check_full_res(ns, &start, module_id, &None) + collector.check_full_res(ns, &start, module_id.into(), &None) { debug!("found partial_res={:?}", res); *partial_res = Some(res); diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 7b0b2f28fdfff..90b797da24915 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -46,7 +46,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { // FIXME(eddyb) is this `doc(hidden)` check needed? if !cx.tcx.get_attrs(def_id).lists(sym::doc).has_word(sym::hidden) { - let impls = get_auto_trait_and_blanket_impls(cx, def_id); + let impls = get_auto_trait_and_blanket_impls(cx, def_id.into()); new_items.extend(impls.filter(|i| cx.inlined.insert(i.def_id))); } }); @@ -117,8 +117,8 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { // Avoid infinite cycles return; } - cleaner.items.insert(target_did); - add_deref_target(map, cleaner, &target_did); + cleaner.items.insert(target_did.into()); + add_deref_target(map, cleaner, &target_did.into()); } } } @@ -126,7 +126,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { // Since only the `DefId` portion of the `Type` instances is known to be same for both the // `Deref` target type and the impl for type positions, this map of types is keyed by // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. - if cleaner.keep_impl_with_def_id(type_did) { + if cleaner.keep_impl_with_def_id(&FakeDefId::new_real(*type_did)) { add_deref_target(&type_did_to_deref_target, &mut cleaner, type_did); } } @@ -163,8 +163,10 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> { fn fold_item(&mut self, i: Item) -> Option { if i.is_struct() || i.is_enum() || i.is_union() { // FIXME(eddyb) is this `doc(hidden)` check needed? - if !self.cx.tcx.get_attrs(i.def_id).lists(sym::doc).has_word(sym::hidden) { - self.impls.extend(get_auto_trait_and_blanket_impls(self.cx, i.def_id)); + if !self.cx.tcx.get_attrs(i.def_id.expect_real()).lists(sym::doc).has_word(sym::hidden) + { + self.impls + .extend(get_auto_trait_and_blanket_impls(self.cx, i.def_id.expect_real())); } } @@ -174,7 +176,7 @@ impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> { #[derive(Default)] struct ItemCollector { - items: FxHashSet, + items: FxHashSet, } impl ItemCollector { @@ -193,7 +195,7 @@ impl DocFolder for ItemCollector { struct BadImplStripper { prims: FxHashSet, - items: FxHashSet, + items: FxHashSet, } impl BadImplStripper { @@ -204,13 +206,13 @@ impl BadImplStripper { } else if let Some(prim) = ty.primitive_type() { self.prims.contains(&prim) } else if let Some(did) = ty.def_id() { - self.keep_impl_with_def_id(&did) + self.keep_impl_with_def_id(&did.into()) } else { false } } - fn keep_impl_with_def_id(&self, did: &DefId) -> bool { + fn keep_impl_with_def_id(&self, did: &FakeDefId) -> bool { self.items.contains(did) } } diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs index c8d2263d81d54..7362cfcb71b7e 100644 --- a/src/librustdoc/passes/doc_test_lints.rs +++ b/src/librustdoc/passes/doc_test_lints.rs @@ -53,7 +53,7 @@ impl crate::doctest::Tester for Tests { } crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool { - if !cx.cache.access_levels.is_public(item.def_id) + if !cx.cache.access_levels.is_public(item.def_id.expect_real()) || matches!( *item.kind, clean::StructFieldItem(_) @@ -105,7 +105,8 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { |lint| lint.build("missing code example in this documentation").emit(), ); } - } else if tests.found_tests > 0 && !cx.cache.access_levels.is_public(item.def_id) { + } else if tests.found_tests > 0 && !cx.cache.access_levels.is_public(item.def_id.expect_real()) + { cx.tcx.struct_span_lint_hir( crate::lint::PRIVATE_DOC_TESTS, hir_id, diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 54c4ed22f1c4b..e5910d081a5d0 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -1,9 +1,8 @@ -use rustc_hir::def_id::DefIdSet; use rustc_span::symbol::sym; use std::mem; use crate::clean; -use crate::clean::{Item, NestedAttributesExt}; +use crate::clean::{FakeDefIdSet, Item, NestedAttributesExt}; use crate::core::DocContext; use crate::fold::{DocFolder, StripItem}; use crate::passes::{ImplStripper, Pass}; @@ -16,7 +15,7 @@ crate const STRIP_HIDDEN: Pass = Pass { /// Strip items marked `#[doc(hidden)]` crate fn strip_hidden(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate { - let mut retained = DefIdSet::default(); + let mut retained = FakeDefIdSet::default(); // strip all #[doc(hidden)] items let krate = { @@ -30,7 +29,7 @@ crate fn strip_hidden(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Cra } struct Stripper<'a> { - retained: &'a mut DefIdSet, + retained: &'a mut FakeDefIdSet, update_retained: bool, } diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs index fc8bbc9715029..18abeb607a17f 100644 --- a/src/librustdoc/passes/strip_private.rs +++ b/src/librustdoc/passes/strip_private.rs @@ -1,6 +1,4 @@ -use rustc_hir::def_id::DefIdSet; - -use crate::clean; +use crate::clean::{self, FakeDefIdSet}; use crate::core::DocContext; use crate::fold::DocFolder; use crate::passes::{ImplStripper, ImportStripper, Pass, Stripper}; @@ -16,7 +14,7 @@ crate const STRIP_PRIVATE: Pass = Pass { /// crate, specified by the `xcrate` flag. crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate { // This stripper collects all *retained* nodes. - let mut retained = DefIdSet::default(); + let mut retained = FakeDefIdSet::default(); // strip all private items { diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 44d54563f27a2..87399256292a8 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -1,12 +1,12 @@ -use rustc_hir::def_id::{DefId, DefIdSet}; +use rustc_hir::def_id::DefId; use rustc_middle::middle::privacy::AccessLevels; use std::mem; -use crate::clean::{self, GetDefId, Item}; +use crate::clean::{self, FakeDefIdSet, GetDefId, Item}; use crate::fold::{DocFolder, StripItem}; crate struct Stripper<'a> { - crate retained: &'a mut DefIdSet, + crate retained: &'a mut FakeDefIdSet, crate access_levels: &'a AccessLevels, crate update_retained: bool, } @@ -42,7 +42,7 @@ impl<'a> DocFolder for Stripper<'a> { | clean::TraitAliasItem(..) | clean::ForeignTypeItem => { if i.def_id.is_local() { - if !self.access_levels.is_exported(i.def_id) { + if !self.access_levels.is_exported(i.def_id.expect_real()) { debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name); return None; } @@ -116,7 +116,7 @@ impl<'a> DocFolder for Stripper<'a> { /// This stripper discards all impls which reference stripped items crate struct ImplStripper<'a> { - crate retained: &'a DefIdSet, + crate retained: &'a FakeDefIdSet, } impl<'a> DocFolder for ImplStripper<'a> { @@ -127,13 +127,14 @@ impl<'a> DocFolder for ImplStripper<'a> { return None; } if let Some(did) = imp.for_.def_id() { - if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did) { + if did.is_local() && !imp.for_.is_generic() && !self.retained.contains(&did.into()) + { debug!("ImplStripper: impl item for stripped type; removing"); return None; } } if let Some(did) = imp.trait_.def_id() { - if did.is_local() && !self.retained.contains(&did) { + if did.is_local() && !self.retained.contains(&did.into()) { debug!("ImplStripper: impl item for stripped trait; removing"); return None; } @@ -141,7 +142,7 @@ impl<'a> DocFolder for ImplStripper<'a> { if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) { for typaram in generics { if let Some(did) = typaram.def_id() { - if did.is_local() && !self.retained.contains(&did) { + if did.is_local() && !self.retained.contains(&did.into()) { debug!( "ImplStripper: stripped item in trait's generics; removing impl" ); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ab9a112380ec4..191d8d5a2ea3b 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -191,7 +191,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { } else { // All items need to be handled here in case someone wishes to link // to them with intra-doc links - self.cx.cache.access_levels.map.insert(did, AccessLevel::Public); + self.cx.cache.access_levels.map.insert(did.into(), AccessLevel::Public); } } } @@ -203,7 +203,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { None => return false, }; - let is_private = !self.cx.cache.access_levels.is_public(res_did); + let is_private = !self.cx.cache.access_levels.is_public(res_did.into()); let is_hidden = inherits_doc_hidden(self.cx.tcx, res_hir_id); // Only inline if requested or if the item would otherwise be stripped.