Skip to content

Commit 0a47792

Browse files
committed
rustdoc-json: Extract Id handling into its own module
I want to work on this in a followup commit, so in this commit I make it self-contained. Contains no code changes, all functions are defined exactly as they were in conversions.rs.
1 parent 249cb84 commit 0a47792

File tree

3 files changed

+85
-74
lines changed

3 files changed

+85
-74
lines changed

src/librustdoc/json/conversions.rs

+2-64
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
use rustc_abi::ExternAbi;
88
use rustc_ast::ast;
99
use rustc_attr_parsing::DeprecatedSince;
10-
use rustc_hir::def::{CtorKind, DefKind};
10+
use rustc_hir::def::CtorKind;
1111
use rustc_hir::def_id::DefId;
1212
use rustc_metadata::rendered_const;
1313
use rustc_middle::{bug, ty};
14-
use rustc_span::{Pos, Symbol, sym};
14+
use rustc_span::{Pos, Symbol};
1515
use rustdoc_json_types::*;
1616

17-
use super::FullItemId;
1817
use crate::clean::{self, ItemId};
1918
use crate::formats::FormatRenderer;
2019
use crate::formats::item_type::ItemType;
@@ -108,67 +107,6 @@ impl JsonRenderer<'_> {
108107
}
109108
}
110109

111-
pub(crate) fn id_from_item_default(&self, item_id: ItemId) -> Id {
112-
self.id_from_item_inner(item_id, None, None)
113-
}
114-
115-
pub(crate) fn id_from_item_inner(
116-
&self,
117-
item_id: ItemId,
118-
name: Option<Symbol>,
119-
extra: Option<Id>,
120-
) -> Id {
121-
let make_part = |def_id: DefId, name: Option<Symbol>, extra: Option<Id>| {
122-
let name = match name {
123-
Some(name) => Some(name),
124-
None => {
125-
// We need this workaround because primitive types' DefId actually refers to
126-
// their parent module, which isn't present in the output JSON items. So
127-
// instead, we directly get the primitive symbol
128-
if matches!(self.tcx.def_kind(def_id), DefKind::Mod)
129-
&& let Some(prim) = self
130-
.tcx
131-
.get_attrs(def_id, sym::rustc_doc_primitive)
132-
.find_map(|attr| attr.value_str())
133-
{
134-
Some(prim)
135-
} else {
136-
self.tcx.opt_item_name(def_id)
137-
}
138-
}
139-
};
140-
141-
FullItemId { def_id, name, extra }
142-
};
143-
144-
let key = match item_id {
145-
ItemId::DefId(did) => (make_part(did, name, extra), None),
146-
ItemId::Blanket { for_, impl_id } => {
147-
(make_part(impl_id, None, None), Some(make_part(for_, name, extra)))
148-
}
149-
ItemId::Auto { for_, trait_ } => {
150-
(make_part(trait_, None, None), Some(make_part(for_, name, extra)))
151-
}
152-
};
153-
154-
let mut interner = self.id_interner.borrow_mut();
155-
let len = interner.len();
156-
*interner
157-
.entry(key)
158-
.or_insert_with(|| Id(len.try_into().expect("too many items in a crate")))
159-
}
160-
161-
pub(crate) fn id_from_item(&self, item: &clean::Item) -> Id {
162-
match item.kind {
163-
clean::ItemKind::ImportItem(ref import) => {
164-
let extra =
165-
import.source.did.map(ItemId::from).map(|i| self.id_from_item_default(i));
166-
self.id_from_item_inner(item.item_id, item.name, extra)
167-
}
168-
_ => self.id_from_item_inner(item.item_id, item.name, None),
169-
}
170-
}
171-
172110
fn ids(&self, items: impl IntoIterator<Item = clean::Item>) -> Vec<Id> {
173111
items
174112
.into_iter()

src/librustdoc/json/ids.rs

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
use rustc_data_structures::fx::FxHashMap;
2+
use rustc_hir::def::DefKind;
3+
use rustc_hir::def_id::DefId;
4+
use rustc_span::{Symbol, sym};
5+
use rustdoc_json_types::{self as types, Id}; // FIXME: Consistant.
6+
7+
use super::JsonRenderer;
8+
use crate::clean::{self, ItemId};
9+
10+
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
11+
pub(super) struct FullItemId {
12+
def_id: DefId,
13+
name: Option<Symbol>,
14+
/// Used to distinguish imports of different items with the same name
15+
extra: Option<types::Id>,
16+
}
17+
18+
pub(super) type IdInterner = FxHashMap<(FullItemId, Option<FullItemId>), types::Id>;
19+
20+
impl JsonRenderer<'_> {
21+
pub(crate) fn id_from_item_default(&self, item_id: ItemId) -> Id {
22+
self.id_from_item_inner(item_id, None, None)
23+
}
24+
25+
pub(crate) fn id_from_item_inner(
26+
&self,
27+
item_id: ItemId,
28+
name: Option<Symbol>,
29+
extra: Option<Id>,
30+
) -> Id {
31+
let make_part = |def_id: DefId, name: Option<Symbol>, extra: Option<Id>| {
32+
let name = match name {
33+
Some(name) => Some(name),
34+
None => {
35+
// We need this workaround because primitive types' DefId actually refers to
36+
// their parent module, which isn't present in the output JSON items. So
37+
// instead, we directly get the primitive symbol
38+
if matches!(self.tcx.def_kind(def_id), DefKind::Mod)
39+
&& let Some(prim) = self
40+
.tcx
41+
.get_attrs(def_id, sym::rustc_doc_primitive)
42+
.find_map(|attr| attr.value_str())
43+
{
44+
Some(prim)
45+
} else {
46+
self.tcx.opt_item_name(def_id)
47+
}
48+
}
49+
};
50+
51+
FullItemId { def_id, name, extra }
52+
};
53+
54+
let key = match item_id {
55+
ItemId::DefId(did) => (make_part(did, name, extra), None),
56+
ItemId::Blanket { for_, impl_id } => {
57+
(make_part(impl_id, None, None), Some(make_part(for_, name, extra)))
58+
}
59+
ItemId::Auto { for_, trait_ } => {
60+
(make_part(trait_, None, None), Some(make_part(for_, name, extra)))
61+
}
62+
};
63+
64+
let mut interner = self.id_interner.borrow_mut();
65+
let len = interner.len();
66+
*interner
67+
.entry(key)
68+
.or_insert_with(|| Id(len.try_into().expect("too many items in a crate")))
69+
}
70+
71+
pub(crate) fn id_from_item(&self, item: &clean::Item) -> Id {
72+
match item.kind {
73+
clean::ItemKind::ImportItem(ref import) => {
74+
let extra =
75+
import.source.did.map(ItemId::from).map(|i| self.id_from_item_default(i));
76+
self.id_from_item_inner(item.item_id, item.name, extra)
77+
}
78+
_ => self.id_from_item_inner(item.item_id, item.name, None),
79+
}
80+
}
81+
}

src/librustdoc/json/mod.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! docs for usage and details.
66
77
mod conversions;
8+
mod ids;
89
mod import_finder;
910

1011
use std::cell::RefCell;
@@ -16,7 +17,6 @@ use std::rc::Rc;
1617
use rustc_hir::def_id::{DefId, DefIdSet};
1718
use rustc_middle::ty::TyCtxt;
1819
use rustc_session::Session;
19-
use rustc_span::Symbol;
2020
use rustc_span::def_id::LOCAL_CRATE;
2121
use rustdoc_json_types as types;
2222
// It's important to use the FxHashMap from rustdoc_json_types here, instead of
@@ -35,14 +35,6 @@ use crate::formats::cache::Cache;
3535
use crate::json::conversions::IntoJson;
3636
use crate::{clean, try_err};
3737

38-
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
39-
struct FullItemId {
40-
def_id: DefId,
41-
name: Option<Symbol>,
42-
/// Used to distinguish imports of different items with the same name
43-
extra: Option<types::Id>,
44-
}
45-
4638
#[derive(Clone)]
4739
pub(crate) struct JsonRenderer<'tcx> {
4840
tcx: TyCtxt<'tcx>,
@@ -55,7 +47,7 @@ pub(crate) struct JsonRenderer<'tcx> {
5547
out_dir: Option<PathBuf>,
5648
cache: Rc<Cache>,
5749
imported_items: DefIdSet,
58-
id_interner: Rc<RefCell<FxHashMap<(FullItemId, Option<FullItemId>), types::Id>>>,
50+
id_interner: Rc<RefCell<ids::IdInterner>>,
5951
}
6052

6153
impl<'tcx> JsonRenderer<'tcx> {

0 commit comments

Comments
 (0)