Skip to content

Commit 5c5fdef

Browse files
Teach rustdoc that macros are now HIR items
1 parent f08d2b5 commit 5c5fdef

File tree

3 files changed

+18
-81
lines changed

3 files changed

+18
-81
lines changed

src/librustdoc/clean/mod.rs

+4-19
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ impl Clean<Item> for doctree::Module<'_> {
9191
items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
9292
items.extend(self.mods.iter().map(|x| x.clean(cx)));
9393
items.extend(self.items.iter().map(|x| x.clean(cx)).flatten());
94-
items.extend(self.macros.iter().map(|x| x.clean(cx)));
9594

9695
// determine if we should display the inner contents or
9796
// the outer `mod` item for the source code.
@@ -1860,6 +1859,10 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
18601859
ItemKind::Fn(ref sig, ref generics, body_id) => {
18611860
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
18621861
}
1862+
ItemKind::Macro { ref macro_def, .. } => MacroItem(Macro {
1863+
source: display_macro_source(cx, name, &macro_def.ast, def_id, &item.vis),
1864+
imported_from: None,
1865+
}),
18631866
ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref item_ids) => {
18641867
let items = item_ids
18651868
.iter()
@@ -2137,24 +2140,6 @@ impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
21372140
}
21382141
}
21392142

2140-
impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
2141-
fn clean(&self, cx: &mut DocContext<'_>) -> Item {
2142-
let (item, renamed) = self;
2143-
let name = renamed.unwrap_or(item.ident.name);
2144-
let def_id = item.def_id.to_def_id();
2145-
2146-
Item::from_hir_id_and_parts(
2147-
item.hir_id(),
2148-
Some(name),
2149-
MacroItem(Macro {
2150-
source: display_macro_source(cx, name, &item.ast, def_id, &item.vis),
2151-
imported_from: None,
2152-
}),
2153-
cx,
2154-
)
2155-
}
2156-
}
2157-
21582143
impl Clean<TypeBinding> for hir::TypeBinding<'_> {
21592144
fn clean(&self, cx: &mut DocContext<'_>) -> TypeBinding {
21602145
TypeBinding { name: self.ident.name, kind: self.kind.clean(cx) }

src/librustdoc/doctree.rs

+2-10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_span::{self, Span, Symbol};
55

66
use rustc_hir as hir;
77

8+
#[derive(Debug)]
89
crate struct Module<'hir> {
910
crate name: Symbol,
1011
crate where_inner: Span,
@@ -13,20 +14,11 @@ crate struct Module<'hir> {
1314
// (item, renamed)
1415
crate items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>)>,
1516
crate foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>,
16-
crate macros: Vec<(&'hir hir::MacroDef<'hir>, Option<Symbol>)>,
1717
}
1818

1919
impl Module<'hir> {
2020
crate fn new(name: Symbol, id: hir::HirId, where_inner: Span) -> Module<'hir> {
21-
Module {
22-
name,
23-
id,
24-
where_inner,
25-
mods: Vec::new(),
26-
items: Vec::new(),
27-
foreigns: Vec::new(),
28-
macros: Vec::new(),
29-
}
21+
Module { name, id, where_inner, mods: Vec::new(), items: Vec::new(), foreigns: Vec::new() }
3022
}
3123

3224
crate fn where_outer(&self, tcx: TyCtxt<'_>) -> Span {

src/librustdoc/visit_ast.rs

+12-52
Original file line numberDiff line numberDiff line change
@@ -73,56 +73,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
7373

7474
crate fn visit(mut self, krate: &'tcx hir::Crate<'_>) -> Module<'tcx> {
7575
let span = krate.module().inner;
76-
let mut top_level_module = self.visit_mod_contents(
76+
let top_level_module = self.visit_mod_contents(
7777
&Spanned { span, node: hir::VisibilityKind::Public },
7878
hir::CRATE_HIR_ID,
7979
&krate.module(),
8080
self.cx.tcx.crate_name(LOCAL_CRATE),
8181
);
82-
// Attach the crate's exported macros to the top-level module.
83-
// In the case of macros 2.0 (`pub macro`), and for built-in `derive`s or attributes as
84-
// well (_e.g._, `Copy`), these are wrongly bundled in there too, so we need to fix that by
85-
// moving them back to their correct locations.
86-
'exported_macros: for def in krate.exported_macros() {
87-
// The `def` of a macro in `exported_macros` should correspond to either:
88-
// - a `#[macro_export] macro_rules!` macro,
89-
// - a built-in `derive` (or attribute) macro such as the ones in `::core`,
90-
// - a `pub macro`.
91-
// Only the last two need to be fixed, thus:
92-
if def.ast.macro_rules {
93-
top_level_module.macros.push((def, None));
94-
continue 'exported_macros;
95-
}
96-
let tcx = self.cx.tcx;
97-
// Note: this is not the same as `.parent_module()`. Indeed, the latter looks
98-
// for the closest module _ancestor_, which is not necessarily a direct parent
99-
// (since a direct parent isn't necessarily a module, c.f. #77828).
100-
let macro_parent_def_id = {
101-
use rustc_middle::ty::DefIdTree;
102-
tcx.parent(def.def_id.to_def_id()).unwrap()
103-
};
104-
let macro_parent_path = tcx.def_path(macro_parent_def_id);
105-
// HACK: rustdoc has no way to lookup `doctree::Module`s by their HirId. Instead,
106-
// lookup the module by its name, by looking at each path segment one at a time.
107-
let mut cur_mod = &mut top_level_module;
108-
for path_segment in macro_parent_path.data {
109-
// Path segments may refer to a module (in which case they belong to the type
110-
// namespace), which is _necessary_ for the macro to be accessible outside it
111-
// (no "associated macros" as of yet). Else we bail with an outer `continue`.
112-
let path_segment_ty_ns = match path_segment.data {
113-
rustc_hir::definitions::DefPathData::TypeNs(symbol) => symbol,
114-
_ => continue 'exported_macros,
115-
};
116-
// Descend into the child module that matches this path segment (if any).
117-
match cur_mod.mods.iter_mut().find(|child| child.name == path_segment_ty_ns) {
118-
Some(child_mod) => cur_mod = &mut *child_mod,
119-
None => continue 'exported_macros,
120-
}
121-
}
122-
let cur_mod_def_id = tcx.hir().local_def_id(cur_mod.id).to_def_id();
123-
assert_eq!(cur_mod_def_id, macro_parent_def_id);
124-
cur_mod.macros.push((def, None));
125-
}
82+
12683
self.cx.cache.exact_paths = self.exact_paths;
12784
top_level_module
12885
}
@@ -238,10 +195,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
238195
self.inlining = prev;
239196
true
240197
}
241-
Node::MacroDef(def) if !glob => {
242-
om.macros.push((def, renamed));
243-
true
244-
}
245198
_ => false,
246199
};
247200
self.view_item_stack.remove(&res_hir_id);
@@ -257,7 +210,13 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
257210
debug!("visiting item {:?}", item);
258211
let name = renamed.unwrap_or(item.ident.name);
259212

260-
if item.vis.node.is_pub() {
213+
let is_pub = if let hir::ItemKind::Macro { is_exported: true, .. } = item.kind {
214+
true
215+
} else {
216+
item.vis.node.is_pub()
217+
};
218+
219+
if is_pub {
261220
self.store_path(item.def_id.to_def_id());
262221
}
263222

@@ -269,7 +228,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
269228
}
270229
}
271230
// If we're inlining, skip private items.
272-
_ if self.inlining && !item.vis.node.is_pub() => {}
231+
_ if self.inlining && !is_pub => {}
273232
hir::ItemKind::GlobalAsm(..) => {}
274233
hir::ItemKind::Use(_, hir::UseKind::ListStem) => {}
275234
hir::ItemKind::Use(ref path, kind) => {
@@ -285,7 +244,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
285244

286245
// If there was a private module in the current path then don't bother inlining
287246
// anything as it will probably be stripped anyway.
288-
if item.vis.node.is_pub() && self.inside_public_path {
247+
if is_pub && self.inside_public_path {
289248
let please_inline = attrs.iter().any(|item| match item.meta_item_list() {
290249
Some(ref list) if item.has_name(sym::doc) => {
291250
list.iter().any(|i| i.has_name(sym::inline))
@@ -311,6 +270,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
311270
om.mods.push(self.visit_mod_contents(&item.vis, item.hir_id(), m, name));
312271
}
313272
hir::ItemKind::Fn(..)
273+
| hir::ItemKind::Macro { .. }
314274
| hir::ItemKind::ExternCrate(..)
315275
| hir::ItemKind::Enum(..)
316276
| hir::ItemKind::Struct(..)

0 commit comments

Comments
 (0)