mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-11 06:24:24 +00:00
Add type to differentiate between fake and real DefId's
This commit is contained in:
parent
7a0f1781d0
commit
b6120bfb35
@ -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<Item = (DefIndex, &DefKey, &DefPathHash)> + '_ {
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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<ast::Attribute> {
|
||||
self.get_crate_data(def_id.krate).get_item_attrs(def_id.index, sess).collect()
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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<Attrs<'_>>,
|
||||
ret: &mut Vec<clean::Item>,
|
||||
) {
|
||||
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,
|
||||
|
@ -533,7 +533,8 @@ impl Clean<Generics> 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<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
|
||||
.collect::<Vec<GenericParamDef>>();
|
||||
|
||||
// param index -> [(DefId of trait, associated type name, type)]
|
||||
let mut impl_trait_proj = FxHashMap::<u32, Vec<(DefId, Symbol, Ty<'tcx>)>>::default();
|
||||
let mut impl_trait_proj = FxHashMap::<u32, Vec<(FakeDefId, Symbol, Ty<'tcx>)>>::default();
|
||||
|
||||
let where_predicates = preds
|
||||
.predicates
|
||||
@ -663,10 +664,11 @@ impl<'a, 'tcx> Clean<Generics> 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<Generics> 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()),
|
||||
|
@ -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<FxHashMap<CrateNum, DefIndex>> = Default::default());
|
||||
crate type FakeDefIdSet = FxHashSet<FakeDefId>;
|
||||
|
||||
#[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<usize> = 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<LocalDefId> {
|
||||
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<DefId> {
|
||||
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<DefIndex> {
|
||||
match self {
|
||||
FakeDefId::Real(id) => Some(id.index),
|
||||
FakeDefId::Fake(_, _) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DefId> 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<ItemKind>,
|
||||
crate def_id: DefId,
|
||||
crate def_id: FakeDefId,
|
||||
|
||||
crate cfg: Option<Arc<Cfg>>,
|
||||
}
|
||||
@ -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<Deprecation> {
|
||||
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<DefId>,
|
||||
pub(crate) did: Option<FakeDefId>,
|
||||
/// The url fragment to append to the link
|
||||
pub(crate) fragment: Option<String>,
|
||||
}
|
||||
@ -1032,7 +1098,7 @@ impl Attributes {
|
||||
}
|
||||
}
|
||||
|
||||
let clean_attr = |(attr, parent_module): (&ast::Attribute, _)| {
|
||||
let clean_attr = |(attr, parent_module): (&ast::Attribute, Option<DefId>)| {
|
||||
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<DefId> {
|
||||
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),
|
||||
|
@ -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<DefId> {
|
||||
if def_id.is_top_level_module() {
|
||||
// The crate root has no parent. Use it as the root instead.
|
||||
|
@ -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<DefId, clean::Constant>,
|
||||
/// Table synthetic type parameter for `impl Trait` in argument position -> bounds
|
||||
crate impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>,
|
||||
crate fake_def_ids: FxHashMap<CrateNum, DefIndex>,
|
||||
/// 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<DefId>,
|
||||
crate inlined: FxHashSet<FakeDefId>,
|
||||
/// 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<HirId> {
|
||||
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<HirId> {
|
||||
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<DefId> for ImplTraitParam {
|
||||
fn from(did: DefId) -> Self {
|
||||
impl From<FakeDefId> for ImplTraitParam {
|
||||
fn from(did: FakeDefId) -> Self {
|
||||
ImplTraitParam::DefId(did)
|
||||
}
|
||||
}
|
||||
|
@ -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<DefId, Vec<Impl>>,
|
||||
crate implementors: FxHashMap<FakeDefId, Vec<Impl>>,
|
||||
|
||||
/// Cache of where external crate documentation can be found.
|
||||
crate extern_locations: FxHashMap<CrateNum, ExternalLocation>,
|
||||
@ -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<DefId, Vec<clean::ItemLink>>,
|
||||
crate intra_doc_links: BTreeMap<FakeDefId, Vec<clean::ItemLink>>,
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
@ -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<Vec<Generic>>
|
||||
.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,
|
||||
})
|
||||
})
|
||||
|
@ -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);
|
||||
|
@ -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<DefId>,
|
||||
crate parent: Option<FakeDefId>,
|
||||
crate parent_idx: Option<usize>,
|
||||
crate search_type: Option<IndexItemFunctionType>,
|
||||
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<DefId>,
|
||||
ty: Option<FakeDefId>,
|
||||
idx: Option<usize>,
|
||||
name: Option<String>,
|
||||
generics: Option<Vec<Generic>>,
|
||||
@ -128,7 +128,7 @@ impl Serialize for RenderType {
|
||||
#[derive(Debug)]
|
||||
crate struct Generic {
|
||||
name: String,
|
||||
defid: Option<DefId>,
|
||||
defid: Option<FakeDefId>,
|
||||
idx: Option<usize>,
|
||||
}
|
||||
|
||||
@ -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<Symbol>),
|
||||
GotoSource(FakeDefId, &'a FxHashSet<Symbol>),
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
@ -270,14 +270,18 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
|
||||
w,
|
||||
"<tr><td><code>{}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,
|
||||
"<tr><td><code>{}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("</code></td></tr>");
|
||||
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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<clean::TypeBindingKind> 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<clean::Type> 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<clean::Import> 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,
|
||||
},
|
||||
}
|
||||
|
@ -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<types::Id> {
|
||||
fn get_trait_implementors(&mut self, id: FakeDefId) -> Vec<types::Id> {
|
||||
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<types::Id> {
|
||||
fn get_impls(&mut self, id: FakeDefId) -> Vec<types::Id> {
|
||||
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,
|
||||
|
@ -111,7 +111,11 @@ impl<'a, 'tcx> DocFolder for SyntaxChecker<'a, 'tcx> {
|
||||
fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
|
||||
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);
|
||||
}
|
||||
|
@ -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<Disambiguator>,
|
||||
path_str: String,
|
||||
extra_fragment: Option<String>,
|
||||
@ -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<DefId>,
|
||||
mod_ids: Vec<FakeDefId>,
|
||||
/// 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<String>), 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);
|
||||
|
@ -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<Item> {
|
||||
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<DefId>,
|
||||
items: FxHashSet<FakeDefId>,
|
||||
}
|
||||
|
||||
impl ItemCollector {
|
||||
@ -193,7 +195,7 @@ impl DocFolder for ItemCollector {
|
||||
|
||||
struct BadImplStripper {
|
||||
prims: FxHashSet<PrimitiveType>,
|
||||
items: FxHashSet<DefId>,
|
||||
items: FxHashSet<FakeDefId>,
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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<DefId>,
|
||||
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"
|
||||
);
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user