#[inline]
crate fn is_local(self) -> bool {
match self {
- ItemId::DefId(id) => id.is_local(),
- _ => false,
+ ItemId::Auto { for_: id, .. }
+ | ItemId::Blanket { for_: id, .. }
+ | ItemId::DefId(id) => id.is_local(),
+ ItemId::Primitive(krate) => krate == LOCAL_CRATE,
}
}
#[inline]
#[track_caller]
- crate fn expect_real(self) -> rustc_hir::def_id::DefId {
- self.as_real()
- .unwrap_or_else(|| panic!("ItemId::expect_real: `{:?}` isn't a real ItemId", self))
+ crate fn expect_def_id(self) -> DefId {
+ self.as_def_id()
+ .unwrap_or_else(|| panic!("ItemId::expect_def_id: `{:?}` isn't a DefId", self))
}
#[inline]
- crate fn as_real(self) -> Option<DefId> {
+ crate fn as_def_id(self) -> Option<DefId> {
match self {
ItemId::DefId(id) => Some(id),
_ => None,
#[inline]
crate fn krate(self) -> CrateNum {
match self {
- ItemId::DefId(id) => id.krate,
- ItemId::Auto { trait_, .. } => trait_.krate,
- ItemId::Blanket { trait_, .. } => trait_.krate,
+ ItemId::Auto { for_: id, .. }
+ | ItemId::Blanket { for_: id, .. }
+ | ItemId::DefId(id) => id.krate,
ItemId::Primitive(krate) => krate,
}
}
crate fn index(self) -> Option<DefIndex> {
match self {
ItemId::DefId(id) => Some(id.index),
- ItemId::Auto { trait_, .. } => Some(trait_.index),
- ItemId::Blanket { trait_, .. } => Some(trait_.index),
- ItemId::Primitive(..) => None,
+ _ => None,
}
}
}
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.expect_real()) }
+ self.def_id.as_def_id().and_then(|did| tcx.lookup_stability(did))
}
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.expect_real()) }
+ self.def_id.as_def_id().and_then(|did| tcx.lookup_const_stability(did))
}
crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option<Deprecation> {
- if self.is_fake() { None } else { tcx.lookup_deprecation(self.def_id.expect_real()) }
+ self.def_id.as_def_id().and_then(|did| tcx.lookup_deprecation(did))
}
crate fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
- if self.is_fake() { false } else { tcx.get_attrs(self.def_id.expect_real()).inner_docs() }
+ self.def_id.as_def_id().map(|did| tcx.get_attrs(did).inner_docs()).unwrap_or(false)
}
crate fn span(&self, tcx: TyCtxt<'_>) -> Span {
kind
{
*span
- } else if self.is_fake() {
- Span::dummy()
} else {
- rustc_span(self.def_id.expect_real(), tcx)
+ self.def_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(|| Span::dummy())
}
}
}
crate fn is_crate(&self) -> bool {
- self.is_mod() && self.def_id.as_real().map_or(false, |did| did.index == CRATE_DEF_INDEX)
+ self.is_mod() && self.def_id.as_def_id().map_or(false, |did| did.index == CRATE_DEF_INDEX)
}
crate fn is_mod(&self) -> bool {
self.type_() == ItemType::Module
_ => false,
}
}
-
- crate fn is_fake(&self) -> bool {
- // FIXME: Find a better way to handle this
- !matches!(self.def_id, ItemId::DefId(..))
- }
}
#[derive(Clone, Debug)]
// 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.expect_real()).or_insert_with(|| {
+ self.cache.traits.entry(item.def_id.expect_def_id()).or_insert_with(|| {
clean::TraitWithExtraInfo {
trait_: t.clone(),
is_notable: item.attrs.has_doc_flag(sym::notable_trait),
// `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.expect_real())
- || self.cache.access_levels.is_public(item.def_id.expect_real())
+ if !self.cache.paths.contains_key(&item.def_id.expect_def_id())
+ || self.cache.access_levels.is_public(item.def_id.expect_def_id())
{
self.cache.paths.insert(
- item.def_id.expect_real(),
+ item.def_id.expect_def_id(),
(self.cache.stack.clone(), item.type_()),
);
}
clean::PrimitiveItem(..) => {
self.cache
.paths
- .insert(item.def_id.expect_real(), (self.cache.stack.clone(), item.type_()));
+ .insert(item.def_id.expect_def_id(), (self.cache.stack.clone(), item.type_()));
}
clean::ExternCrateItem { .. }
| clean::StructItem(..)
| clean::UnionItem(..)
| clean::VariantItem(..) => {
- self.cache.parent_stack.push(item.def_id.expect_real());
+ self.cache.parent_stack.push(item.def_id.expect_def_id());
self.cache.parent_is_trait_impl = false;
true
}
// 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.expect_real());
+ let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
if vis_did.index == CRATE_DEF_INDEX {
"pub(crate) ".to_owned()
&self.shared.style_files,
)
} else {
- if let Some(&(ref names, ty)) = self.cache.paths.get(&it.def_id.expect_real()) {
+ if let Some(&(ref names, ty)) = self.cache.paths.get(&it.def_id.expect_def_id()) {
let mut path = String::new();
for name in &names[..names.len() - 1] {
path.push_str(name);
AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id),
AssocItemLink::Anchor(None) => anchor,
AssocItemLink::GotoSource(did, _) => {
- href(did.expect_real(), cx).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
+ href(did.expect_def_id(), cx).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor)
}
}
}
ItemType::TyMethod
};
- href(did.expect_real(), cx)
+ href(did.expect_def_id(), cx)
.map(|p| format!("{}#{}.{}", p.0, ty, name))
.unwrap_or_else(|| format!("#{}.{}", ty, name))
}
}
fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) {
- let did = it.def_id.expect_real();
+ let did = it.def_id.expect_def_id();
if let Some(v) = cx.cache.impls.get(&did) {
let mut used_links = FxHashSet::default();
let cache = cx.cache();
"</div>",
);
- if let Some(implementors) = cx.cache.implementors.get(&it.def_id.expect_real()) {
+ if let Some(implementors) = cx.cache.implementors.get(&it.def_id.expect_def_id()) {
let cache = cx.cache();
let mut res = implementors
.iter()
w,
"<div class=\"item-left\"><code>{}extern crate {} as {};",
myitem.visibility.print_with_space(myitem.def_id, cx),
- anchor(myitem.def_id.expect_real(), &*src.as_str(), cx),
+ anchor(myitem.def_id.expect_def_id(), &*src.as_str(), cx),
myitem.name.as_ref().unwrap(),
),
None => write!(
"<div class=\"item-left\"><code>{}extern crate {};",
myitem.visibility.print_with_space(myitem.def_id, cx),
anchor(
- myitem.def_id.expect_real(),
+ myitem.def_id.expect_def_id(),
&*myitem.name.as_ref().unwrap().as_str(),
cx
),
}
// If there are methods directly on this trait object, render them here.
- render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All);
+ render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All);
- if let Some(implementors) = cx.cache.implementors.get(&it.def_id.expect_real()) {
+ if let Some(implementors) = cx.cache.implementors.get(&it.def_id.expect_def_id()) {
// The DefId is for the first Type found with that name. The bool is
// if any Types with the same name but different DefId have been found.
let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
path = if it.def_id.is_local() {
cx.current.join("/")
} else {
- let (ref path, _) = cx.cache.external_paths[&it.def_id.expect_real()];
+ let (ref path, _) = cx.cache.external_paths[&it.def_id.expect_def_id()];
path[..path.len() - 1].join("/")
},
ty = it.type_(),
// 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.expect_real(), AssocItemRender::All)
+ render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All)
}
fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) {
// 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.expect_real(), AssocItemRender::All)
+ render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All)
}
fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
document(w, cx, it, None);
- let def_id = it.def_id.expect_real();
+ let def_id = it.def_id.expect_def_id();
// Render any items associated directly to this alias, as otherwise they
// 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
document(w, cx, field, Some(it));
}
}
- let def_id = it.def_id.expect_real();
+ let def_id = it.def_id.expect_def_id();
render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
document_type_layout(w, cx, def_id);
}
}
}
}
- let def_id = it.def_id.expect_real();
+ let def_id = it.def_id.expect_def_id();
render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
document_type_layout(w, cx, def_id);
}
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.expect_real(), AssocItemRender::All)
+ render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All)
}
fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
}
}
}
- let def_id = it.def_id.expect_real();
+ let def_id = it.def_id.expect_def_id();
render_assoc_items(w, cx, it, def_id, AssocItemRender::All);
document_type_layout(w, cx, def_id);
}
document(w, cx, it, None);
- render_assoc_items(w, cx, it, it.def_id.expect_real(), AssocItemRender::All)
+ render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All)
}
fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
let id = item.def_id;
if let Some(mut new_item) = self.convert_item(item) {
if let types::ItemEnum::Trait(ref mut t) = new_item.inner {
- t.implementors = self.get_trait_implementors(id.expect_real())
+ t.implementors = self.get_trait_implementors(id.expect_def_id())
} else if let types::ItemEnum::Struct(ref mut s) = new_item.inner {
- s.impls = self.get_impls(id.expect_real())
+ s.impls = self.get_impls(id.expect_def_id())
} else if let types::ItemEnum::Enum(ref mut e) = new_item.inner {
- e.impls = self.get_impls(id.expect_real())
+ e.impls = self.get_impls(id.expect_def_id())
}
let removed = self.index.borrow_mut().insert(from_item_id(id), new_item.clone());
let filename = i.span(self.ctx.tcx).filename(self.ctx.sess());
let has_doc_example = tests.found_tests != 0;
- // The `expect_real()` should be okay because `local_def_id_to_hir_id`
+ // The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
// would presumably panic if a fake `DefIndex` were passed.
let hir_id = self
.ctx
.tcx
.hir()
- .local_def_id_to_hir_id(i.def_id.expect_real().expect_local());
+ .local_def_id_to_hir_id(i.def_id.expect_def_id().expect_local());
let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id);
// `missing_docs` is allow-by-default, so don't treat this as ignoring the item
// unless the user had an explicit `allow`
return;
}
- let local_id = match item.def_id.as_real().and_then(|x| x.as_local()) {
+ let local_id = match item.def_id.as_def_id().and_then(|x| x.as_local()) {
Some(id) => id,
// We don't need to check the syntax for other crates so returning
// without doing anything should not be a problem.
let sp = item.attr_span(self.cx.tcx);
let extra = crate::html::markdown::ExtraInfo::new_did(
self.cx.tcx,
- item.def_id.expect_real(),
+ item.def_id.expect_def_id(),
sp,
);
for code_block in markdown::rust_code_blocks(&dox, &extra) {
fn fold_item(&mut self, item: Item) -> Option<Item> {
use rustc_middle::ty::DefIdTree;
- let parent_node = if item.is_fake() {
- None
- } else {
- find_nearest_parent_module(self.cx.tcx, item.def_id.expect_real())
- };
-
+ let parent_node =
+ item.def_id.as_def_id().and_then(|did| find_nearest_parent_module(self.cx.tcx, did));
if parent_node.is_some() {
trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id);
}
// find item's parent to resolve `Self` in item's docs below
debug!("looking for the `Self` type");
- 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.expect_real()), DefKind::Field)
- && matches!(
- self.cx.tcx.def_kind(self.cx.tcx.parent(item.def_id.expect_real()).unwrap()),
- DefKind::Variant
- ))
- {
- 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.expect_real()),
- DefKind::AssocConst
- | DefKind::AssocFn
- | DefKind::AssocTy
- | DefKind::Variant
- | DefKind::Field
- ) {
- 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.expect_real()) {
- let parent_kind = self.cx.tcx.def_kind(parent);
- Some(if parent_kind == DefKind::Impl { parent } else { item.def_id.expect_real() })
- } else {
- Some(item.def_id.expect_real())
+ let self_id = match item.def_id.as_def_id() {
+ None => None,
+ Some(did)
+ if (matches!(self.cx.tcx.def_kind(did), DefKind::Field)
+ && matches!(
+ self.cx.tcx.def_kind(self.cx.tcx.parent(did).unwrap()),
+ DefKind::Variant
+ )) =>
+ {
+ self.cx.tcx.parent(did).and_then(|item_id| self.cx.tcx.parent(item_id))
+ }
+ Some(did)
+ if matches!(
+ self.cx.tcx.def_kind(did),
+ DefKind::AssocConst
+ | DefKind::AssocFn
+ | DefKind::AssocTy
+ | DefKind::Variant
+ | DefKind::Field
+ ) =>
+ {
+ self.cx.tcx.parent(did)
+ }
+ Some(did) => match self.cx.tcx.parent(did) {
+ // 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.
+ Some(parent) => {
+ let parent_kind = self.cx.tcx.def_kind(parent);
+ Some(if parent_kind == DefKind::Impl { parent } else { did })
+ }
+ None => Some(did),
+ },
};
// FIXME(jynelson): this shouldn't go through stringification, rustdoc should just use the DefId directly
let inner_docs = item.inner_docs(self.cx.tcx);
if item.is_mod() && inner_docs {
- self.mod_ids.push(item.def_id.expect_real());
+ self.mod_ids.push(item.def_id.expect_def_id());
}
// We want to resolve in the lexical scope of the documentation.
Some(if item.is_mod() {
if !inner_docs {
- self.mod_ids.push(item.def_id.expect_real());
+ self.mod_ids.push(item.def_id.expect_def_id());
}
let ret = self.fold_item_recur(item);
// item can be non-local e.g. when using #[doc(primitive = "pointer")]
if let Some((src_id, dst_id)) = id
.as_local()
- // The `expect_real()` should be okay because `local_def_id_to_hir_id`
+ // The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
// would presumably panic if a fake `DefIndex` were passed.
.and_then(|dst_id| {
- item.def_id.expect_real().as_local().map(|src_id| (src_id, dst_id))
+ item.def_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
})
{
let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id);
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.expect_real()).lists(sym::doc).has_word(sym::hidden)
+ if !self
+ .cx
+ .tcx
+ .get_attrs(i.def_id.expect_def_id())
+ .lists(sym::doc)
+ .has_word(sym::hidden)
{
self.impls
- .extend(get_auto_trait_and_blanket_impls(self.cx, i.def_id.expect_real()));
+ .extend(get_auto_trait_and_blanket_impls(self.cx, i.def_id.expect_def_id()));
}
}
}
crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool {
- if !cx.cache.access_levels.is_public(item.def_id.expect_real())
+ if !cx.cache.access_levels.is_public(item.def_id.expect_def_id())
|| matches!(
*item.kind,
clean::StructFieldItem(_)
{
return false;
}
- // The `expect_real()` should be okay because `local_def_id_to_hir_id`
+ // The `expect_def_id()` should be okay because `local_def_id_to_hir_id`
// would presumably panic if a fake `DefIndex` were passed.
- let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_real().expect_local());
+ let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_def_id().expect_local());
if cx.tcx.hir().attrs(hir_id).lists(sym::doc).has_word(sym::hidden)
|| inherits_doc_hidden(cx.tcx, hir_id)
{
|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.expect_real())
+ } else if tests.found_tests > 0
+ && !cx.cache.access_levels.is_public(item.def_id.expect_def_id())
{
cx.tcx.struct_span_lint_hir(
crate::lint::PRIVATE_DOC_TESTS,
| clean::TraitAliasItem(..)
| clean::ForeignTypeItem => {
if i.def_id.is_local() {
- if !self.access_levels.is_exported(i.def_id.expect_real()) {
+ if !self.access_levels.is_exported(i.def_id.expect_def_id()) {
debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name);
return None;
}