Skip to content

Commit 9a27044

Browse files
committed
Auto merge of #86644 - Stupremee:replace-fakedefids-with-itemid, r=jyn514
rustdoc: Replace `FakeDefId` with new `ItemId` type Follow up from #84707 `@Manishearth` [suggested](#84707 (comment)) that there should be a new `ItemId` type that can distinguish between auto traits, normal ids, and blanket impls instead of using `FakeDefId`s. This type is introduced by this PR. There are still some `FIXME`s left, because I was unsure what the best solution for them would be. Especially the naming in general now is a bit weird right now and needs to be cleaned up. Now there are no "fake" ids so the `is_fake` method on `Item` does not really make sense and maybe the methods on `ItemId` should be renamed too? Also, we need to represent the new item ids in the JSON backend somehow.
2 parents d5a406b + a89912c commit 9a27044

20 files changed

+188
-179
lines changed

src/librustdoc/clean/auto_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
113113
name: None,
114114
attrs: Default::default(),
115115
visibility: Inherited,
116-
def_id: FakeDefId::new_fake(item_def_id.krate),
116+
def_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id },
117117
kind: box ImplItem(Impl {
118118
span: Span::dummy(),
119119
unsafety: hir::Unsafety::Normal,

src/librustdoc/clean/blanket_impl.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
9696
name: None,
9797
attrs: Default::default(),
9898
visibility: Inherited,
99-
def_id: FakeDefId::new_fake(item_def_id.krate),
99+
def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id },
100100
kind: box ImplItem(Impl {
101101
span: self.cx.tcx.def_span(impl_def_id).clean(self.cx),
102102
unsafety: hir::Unsafety::Normal,

src/librustdoc/clean/inline.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_span::hygiene::MacroKind;
1515
use rustc_span::symbol::{kw, sym, Symbol};
1616

1717
use crate::clean::{
18-
self, utils, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, Type,
18+
self, utils, Attributes, AttributesExt, GetDefId, ItemId, NestedAttributesExt, Type,
1919
};
2020
use crate::core::DocContext;
2121
use crate::formats::item_type::ItemType;
@@ -483,10 +483,11 @@ fn build_module(
483483
}
484484
if let Res::PrimTy(p) = item.res {
485485
// Primitive types can't be inlined so generate an import instead.
486+
let prim_ty = clean::PrimitiveType::from(p);
486487
items.push(clean::Item {
487488
name: None,
488489
attrs: box clean::Attributes::default(),
489-
def_id: FakeDefId::new_fake(did.krate),
490+
def_id: ItemId::Primitive(prim_ty, did.krate),
490491
visibility: clean::Public,
491492
kind: box clean::ImportItem(clean::Import::new_simple(
492493
item.ident.name,
@@ -495,7 +496,7 @@ fn build_module(
495496
global: false,
496497
res: item.res,
497498
segments: vec![clean::PathSegment {
498-
name: clean::PrimitiveType::from(p).as_sym(),
499+
name: prim_ty.as_sym(),
499500
args: clean::GenericArgs::AngleBracketed {
500501
args: Vec::new(),
501502
bindings: Vec::new(),

src/librustdoc/clean/types.rs

+39-50
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::cell::{Cell, RefCell};
1+
use std::cell::RefCell;
22
use std::default::Default;
33
use std::hash::{Hash, Hasher};
44
use std::iter::FromIterator;
@@ -48,73 +48,68 @@ use self::ItemKind::*;
4848
use self::SelfTy::*;
4949
use self::Type::*;
5050

51-
crate type FakeDefIdSet = FxHashSet<FakeDefId>;
51+
crate type ItemIdSet = FxHashSet<ItemId>;
5252

53-
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
54-
crate enum FakeDefId {
55-
Real(DefId),
56-
Fake(DefIndex, CrateNum),
53+
#[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)]
54+
crate enum ItemId {
55+
/// A "normal" item that uses a [`DefId`] for identification.
56+
DefId(DefId),
57+
/// Identifier that is used for auto traits.
58+
Auto { trait_: DefId, for_: DefId },
59+
/// Identifier that is used for blanket implementations.
60+
Blanket { impl_id: DefId, for_: DefId },
61+
/// Identifier for primitive types.
62+
Primitive(PrimitiveType, CrateNum),
5763
}
5864

59-
impl FakeDefId {
60-
#[cfg(parallel_compiler)]
61-
crate fn new_fake(crate: CrateNum) -> Self {
62-
unimplemented!("")
63-
}
64-
65-
#[cfg(not(parallel_compiler))]
66-
crate fn new_fake(krate: CrateNum) -> Self {
67-
thread_local!(static FAKE_DEF_ID_COUNTER: Cell<usize> = Cell::new(0));
68-
let id = FAKE_DEF_ID_COUNTER.with(|id| {
69-
let tmp = id.get();
70-
id.set(tmp + 1);
71-
tmp
72-
});
73-
Self::Fake(DefIndex::from(id), krate)
74-
}
75-
65+
impl ItemId {
7666
#[inline]
7767
crate fn is_local(self) -> bool {
7868
match self {
79-
FakeDefId::Real(id) => id.is_local(),
80-
FakeDefId::Fake(_, krate) => krate == LOCAL_CRATE,
69+
ItemId::Auto { for_: id, .. }
70+
| ItemId::Blanket { for_: id, .. }
71+
| ItemId::DefId(id) => id.is_local(),
72+
ItemId::Primitive(_, krate) => krate == LOCAL_CRATE,
8173
}
8274
}
8375

8476
#[inline]
8577
#[track_caller]
86-
crate fn expect_real(self) -> rustc_hir::def_id::DefId {
87-
self.as_real().unwrap_or_else(|| panic!("FakeDefId::expect_real: `{:?}` isn't real", self))
78+
crate fn expect_def_id(self) -> DefId {
79+
self.as_def_id()
80+
.unwrap_or_else(|| panic!("ItemId::expect_def_id: `{:?}` isn't a DefId", self))
8881
}
8982

9083
#[inline]
91-
crate fn as_real(self) -> Option<DefId> {
84+
crate fn as_def_id(self) -> Option<DefId> {
9285
match self {
93-
FakeDefId::Real(id) => Some(id),
94-
FakeDefId::Fake(_, _) => None,
86+
ItemId::DefId(id) => Some(id),
87+
_ => None,
9588
}
9689
}
9790

9891
#[inline]
9992
crate fn krate(self) -> CrateNum {
10093
match self {
101-
FakeDefId::Real(id) => id.krate,
102-
FakeDefId::Fake(_, krate) => krate,
94+
ItemId::Auto { for_: id, .. }
95+
| ItemId::Blanket { for_: id, .. }
96+
| ItemId::DefId(id) => id.krate,
97+
ItemId::Primitive(_, krate) => krate,
10398
}
10499
}
105100

106101
#[inline]
107102
crate fn index(self) -> Option<DefIndex> {
108103
match self {
109-
FakeDefId::Real(id) => Some(id.index),
110-
FakeDefId::Fake(_, _) => None,
104+
ItemId::DefId(id) => Some(id.index),
105+
_ => None,
111106
}
112107
}
113108
}
114109

115-
impl From<DefId> for FakeDefId {
110+
impl From<DefId> for ItemId {
116111
fn from(id: DefId) -> Self {
117-
Self::Real(id)
112+
Self::DefId(id)
118113
}
119114
}
120115

@@ -338,14 +333,14 @@ crate struct Item {
338333
/// Information about this item that is specific to what kind of item it is.
339334
/// E.g., struct vs enum vs function.
340335
crate kind: Box<ItemKind>,
341-
crate def_id: FakeDefId,
336+
crate def_id: ItemId,
342337

343338
crate cfg: Option<Arc<Cfg>>,
344339
}
345340

346341
// `Item` is used a lot. Make sure it doesn't unintentionally get bigger.
347342
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
348-
rustc_data_structures::static_assert_size!(Item, 48);
343+
rustc_data_structures::static_assert_size!(Item, 56);
349344

350345
crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span {
351346
Span::from_rustc_span(def_id.as_local().map_or_else(
@@ -359,19 +354,19 @@ crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span {
359354

360355
impl Item {
361356
crate fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx Stability> {
362-
if self.is_fake() { None } else { tcx.lookup_stability(self.def_id.expect_real()) }
357+
self.def_id.as_def_id().and_then(|did| tcx.lookup_stability(did))
363358
}
364359

365360
crate fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option<&'tcx ConstStability> {
366-
if self.is_fake() { None } else { tcx.lookup_const_stability(self.def_id.expect_real()) }
361+
self.def_id.as_def_id().and_then(|did| tcx.lookup_const_stability(did))
367362
}
368363

369364
crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option<Deprecation> {
370-
if self.is_fake() { None } else { tcx.lookup_deprecation(self.def_id.expect_real()) }
365+
self.def_id.as_def_id().and_then(|did| tcx.lookup_deprecation(did))
371366
}
372367

373368
crate fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool {
374-
if self.is_fake() { false } else { tcx.get_attrs(self.def_id.expect_real()).inner_docs() }
369+
self.def_id.as_def_id().map(|did| tcx.get_attrs(did).inner_docs()).unwrap_or(false)
375370
}
376371

377372
crate fn span(&self, tcx: TyCtxt<'_>) -> Span {
@@ -383,10 +378,8 @@ impl Item {
383378
kind
384379
{
385380
*span
386-
} else if self.is_fake() {
387-
Span::dummy()
388381
} else {
389-
rustc_span(self.def_id.expect_real(), tcx)
382+
self.def_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(|| Span::dummy())
390383
}
391384
}
392385

@@ -551,7 +544,7 @@ impl Item {
551544
}
552545

553546
crate fn is_crate(&self) -> bool {
554-
self.is_mod() && self.def_id.as_real().map_or(false, |did| did.index == CRATE_DEF_INDEX)
547+
self.is_mod() && self.def_id.as_def_id().map_or(false, |did| did.index == CRATE_DEF_INDEX)
555548
}
556549
crate fn is_mod(&self) -> bool {
557550
self.type_() == ItemType::Module
@@ -662,10 +655,6 @@ impl Item {
662655
_ => false,
663656
}
664657
}
665-
666-
crate fn is_fake(&self) -> bool {
667-
matches!(self.def_id, FakeDefId::Fake(_, _))
668-
}
669658
}
670659

671660
#[derive(Clone, Debug)]

src/librustdoc/core.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use std::mem;
3030
use std::rc::Rc;
3131

3232
use crate::clean::inline::build_external_trait;
33-
use crate::clean::{self, FakeDefId, TraitWithExtraInfo};
33+
use crate::clean::{self, ItemId, TraitWithExtraInfo};
3434
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
3535
use crate::formats::cache::Cache;
3636
use crate::passes::{self, Condition::*, ConditionalPass};
@@ -78,7 +78,7 @@ crate struct DocContext<'tcx> {
7878
/// This same cache is used throughout rustdoc, including in [`crate::html::render`].
7979
crate cache: Cache,
8080
/// Used by [`clean::inline`] to tell if an item has already been inlined.
81-
crate inlined: FxHashSet<FakeDefId>,
81+
crate inlined: FxHashSet<ItemId>,
8282
/// Used by `calculate_doc_coverage`.
8383
crate output_format: OutputFormat,
8484
}
@@ -128,12 +128,13 @@ impl<'tcx> DocContext<'tcx> {
128128

129129
/// Like `hir().local_def_id_to_hir_id()`, but skips calling it on fake DefIds.
130130
/// (This avoids a slice-index-out-of-bounds panic.)
131-
crate fn as_local_hir_id(tcx: TyCtxt<'_>, def_id: FakeDefId) -> Option<HirId> {
131+
crate fn as_local_hir_id(tcx: TyCtxt<'_>, def_id: ItemId) -> Option<HirId> {
132132
match def_id {
133-
FakeDefId::Real(real_id) => {
133+
ItemId::DefId(real_id) => {
134134
real_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
135135
}
136-
FakeDefId::Fake(_, _) => None,
136+
// FIXME: Can this be `Some` for `Auto` or `Blanket`?
137+
_ => None,
137138
}
138139
}
139140
}

src/librustdoc/formats/cache.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc_middle::middle::privacy::AccessLevels;
88
use rustc_middle::ty::TyCtxt;
99
use rustc_span::symbol::sym;
1010

11-
use crate::clean::{self, FakeDefId, GetDefId};
11+
use crate::clean::{self, GetDefId, ItemId};
1212
use crate::fold::DocFolder;
1313
use crate::formats::item_type::ItemType;
1414
use crate::formats::Impl;
@@ -122,7 +122,7 @@ crate struct Cache {
122122
/// All intra-doc links resolved so far.
123123
///
124124
/// Links are indexed by the DefId of the item they document.
125-
crate intra_doc_links: BTreeMap<FakeDefId, Vec<clean::ItemLink>>,
125+
crate intra_doc_links: FxHashMap<ItemId, Vec<clean::ItemLink>>,
126126
}
127127

128128
/// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`.
@@ -215,7 +215,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
215215
// Propagate a trait method's documentation to all implementors of the
216216
// trait.
217217
if let clean::TraitItem(ref t) = *item.kind {
218-
self.cache.traits.entry(item.def_id.expect_real()).or_insert_with(|| {
218+
self.cache.traits.entry(item.def_id.expect_def_id()).or_insert_with(|| {
219219
clean::TraitWithExtraInfo {
220220
trait_: t.clone(),
221221
is_notable: item.attrs.has_doc_flag(sym::notable_trait),
@@ -348,11 +348,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
348348
// `public_items` map, so we can skip inserting into the
349349
// paths map if there was already an entry present and we're
350350
// not a public item.
351-
if !self.cache.paths.contains_key(&item.def_id.expect_real())
352-
|| self.cache.access_levels.is_public(item.def_id.expect_real())
351+
if !self.cache.paths.contains_key(&item.def_id.expect_def_id())
352+
|| self.cache.access_levels.is_public(item.def_id.expect_def_id())
353353
{
354354
self.cache.paths.insert(
355-
item.def_id.expect_real(),
355+
item.def_id.expect_def_id(),
356356
(self.cache.stack.clone(), item.type_()),
357357
);
358358
}
@@ -361,7 +361,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
361361
clean::PrimitiveItem(..) => {
362362
self.cache
363363
.paths
364-
.insert(item.def_id.expect_real(), (self.cache.stack.clone(), item.type_()));
364+
.insert(item.def_id.expect_def_id(), (self.cache.stack.clone(), item.type_()));
365365
}
366366

367367
clean::ExternCrateItem { .. }
@@ -391,7 +391,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
391391
| clean::StructItem(..)
392392
| clean::UnionItem(..)
393393
| clean::VariantItem(..) => {
394-
self.cache.parent_stack.push(item.def_id.expect_real());
394+
self.cache.parent_stack.push(item.def_id.expect_def_id());
395395
self.cache.parent_is_trait_impl = false;
396396
true
397397
}

src/librustdoc/html/format.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use rustc_span::def_id::CRATE_DEF_INDEX;
1919
use rustc_target::spec::abi::Abi;
2020

2121
use crate::clean::{
22-
self, utils::find_nearest_parent_module, ExternalCrate, FakeDefId, GetDefId, PrimitiveType,
22+
self, utils::find_nearest_parent_module, ExternalCrate, GetDefId, ItemId, PrimitiveType,
2323
};
2424
use crate::formats::item_type::ItemType;
2525
use crate::html::escape::Escape;
@@ -1181,7 +1181,7 @@ impl clean::FnDecl {
11811181
impl clean::Visibility {
11821182
crate fn print_with_space<'a, 'tcx: 'a>(
11831183
self,
1184-
item_did: FakeDefId,
1184+
item_did: ItemId,
11851185
cx: &'a Context<'tcx>,
11861186
) -> impl fmt::Display + 'a + Captures<'tcx> {
11871187
let to_print = match self {
@@ -1191,7 +1191,7 @@ impl clean::Visibility {
11911191
// FIXME(camelid): This may not work correctly if `item_did` is a module.
11921192
// However, rustdoc currently never displays a module's
11931193
// visibility, so it shouldn't matter.
1194-
let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_real());
1194+
let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
11951195

11961196
if vis_did.index == CRATE_DEF_INDEX {
11971197
"pub(crate) ".to_owned()

src/librustdoc/html/render/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ impl<'tcx> Context<'tcx> {
230230
&self.shared.style_files,
231231
)
232232
} else {
233-
if let Some(&(ref names, ty)) = self.cache.paths.get(&it.def_id.expect_real()) {
233+
if let Some(&(ref names, ty)) = self.cache.paths.get(&it.def_id.expect_def_id()) {
234234
let mut path = String::new();
235235
for name in &names[..names.len() - 1] {
236236
path.push_str(name);

0 commit comments

Comments
 (0)