Skip to content

Commit 35bd52e

Browse files
authored
Rollup merge of #110279 - GuillaumeGomez:compiler-macro-derive, r=notriddle
rustdoc: Correctly handle built-in compiler proc-macros as proc-macro and not macro Part of #110111. There were actually one issue split in two parts: * Compiler built-in proc-macro were incorrectly considered as macros and not proc-macros. * Re-exports of compiler built-in proc-macros were considering them as macros. Both issues can be fixed by looking at the `MacroKind` variant instead of just relying on information extracted later on. r? ``@fmease``
2 parents f3c6955 + 80c4323 commit 35bd52e

File tree

4 files changed

+78
-44
lines changed

4 files changed

+78
-44
lines changed

src/librustdoc/clean/inline.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ pub(crate) fn try_inline(
111111
clean::ConstantItem(build_const(cx, did))
112112
}
113113
Res::Def(DefKind::Macro(kind), did) => {
114-
let mac = build_macro(cx, did, name, import_def_id);
114+
let mac = build_macro(cx, did, name, import_def_id, kind);
115115

116116
let type_kind = match kind {
117117
MacroKind::Bang => ItemType::Macro,
@@ -651,18 +651,24 @@ fn build_macro(
651651
def_id: DefId,
652652
name: Symbol,
653653
import_def_id: Option<DefId>,
654+
macro_kind: MacroKind,
654655
) -> clean::ItemKind {
655656
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
656-
LoadedMacro::MacroDef(item_def, _) => {
657-
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
658-
let vis = cx.tcx.visibility(import_def_id.unwrap_or(def_id));
659-
clean::MacroItem(clean::Macro {
660-
source: utils::display_macro_source(cx, name, def, def_id, vis),
661-
})
662-
} else {
663-
unreachable!()
657+
LoadedMacro::MacroDef(item_def, _) => match macro_kind {
658+
MacroKind::Bang => {
659+
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
660+
let vis = cx.tcx.visibility(import_def_id.unwrap_or(def_id));
661+
clean::MacroItem(clean::Macro {
662+
source: utils::display_macro_source(cx, name, def, def_id, vis),
663+
})
664+
} else {
665+
unreachable!()
666+
}
664667
}
665-
}
668+
MacroKind::Derive | MacroKind::Attr => {
669+
clean::ProcMacroItem(clean::ProcMacro { kind: macro_kind, helpers: Vec::new() })
670+
}
671+
},
666672
LoadedMacro::ProcMacro(ext) => clean::ProcMacroItem(clean::ProcMacro {
667673
kind: ext.macro_kind(),
668674
helpers: ext.helper_attrs,

src/librustdoc/clean/mod.rs

+39-30
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,38 @@ fn clean_ty_generics<'tcx>(
909909
}
910910
}
911911

912+
fn clean_proc_macro<'tcx>(
913+
item: &hir::Item<'tcx>,
914+
name: &mut Symbol,
915+
kind: MacroKind,
916+
cx: &mut DocContext<'tcx>,
917+
) -> ItemKind {
918+
let attrs = cx.tcx.hir().attrs(item.hir_id());
919+
if kind == MacroKind::Derive &&
920+
let Some(derive_name) = attrs
921+
.lists(sym::proc_macro_derive)
922+
.find_map(|mi| mi.ident())
923+
{
924+
*name = derive_name.name;
925+
}
926+
927+
let mut helpers = Vec::new();
928+
for mi in attrs.lists(sym::proc_macro_derive) {
929+
if !mi.has_name(sym::attributes) {
930+
continue;
931+
}
932+
933+
if let Some(list) = mi.meta_item_list() {
934+
for inner_mi in list {
935+
if let Some(ident) = inner_mi.ident() {
936+
helpers.push(ident.name);
937+
}
938+
}
939+
}
940+
}
941+
ProcMacroItem(ProcMacro { kind, helpers })
942+
}
943+
912944
fn clean_fn_or_proc_macro<'tcx>(
913945
item: &hir::Item<'tcx>,
914946
sig: &hir::FnSig<'tcx>,
@@ -930,31 +962,7 @@ fn clean_fn_or_proc_macro<'tcx>(
930962
}
931963
});
932964
match macro_kind {
933-
Some(kind) => {
934-
if kind == MacroKind::Derive {
935-
*name = attrs
936-
.lists(sym::proc_macro_derive)
937-
.find_map(|mi| mi.ident())
938-
.expect("proc-macro derives require a name")
939-
.name;
940-
}
941-
942-
let mut helpers = Vec::new();
943-
for mi in attrs.lists(sym::proc_macro_derive) {
944-
if !mi.has_name(sym::attributes) {
945-
continue;
946-
}
947-
948-
if let Some(list) = mi.meta_item_list() {
949-
for inner_mi in list {
950-
if let Some(ident) = inner_mi.ident() {
951-
helpers.push(ident.name);
952-
}
953-
}
954-
}
955-
}
956-
ProcMacroItem(ProcMacro { kind, helpers })
957-
}
965+
Some(kind) => clean_proc_macro(item, name, kind, cx),
958966
None => {
959967
let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id));
960968
clean_fn_decl_legacy_const_generics(&mut func, attrs);
@@ -2247,16 +2255,17 @@ fn clean_maybe_renamed_item<'tcx>(
22472255
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
22482256
}),
22492257
ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx),
2250-
// proc macros can have a name set by attributes
2251-
ItemKind::Fn(ref sig, generics, body_id) => {
2252-
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
2253-
}
2254-
ItemKind::Macro(ref macro_def, _) => {
2258+
ItemKind::Macro(ref macro_def, MacroKind::Bang) => {
22552259
let ty_vis = cx.tcx.visibility(def_id);
22562260
MacroItem(Macro {
22572261
source: display_macro_source(cx, name, macro_def, def_id, ty_vis),
22582262
})
22592263
}
2264+
ItemKind::Macro(_, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx),
2265+
// proc macros can have a name set by attributes
2266+
ItemKind::Fn(ref sig, generics, body_id) => {
2267+
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
2268+
}
22602269
ItemKind::Trait(_, _, generics, bounds, item_ids) => {
22612270
let items = item_ids
22622271
.iter()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// This test ensures that compiler builtin proc-macros are considered as such.
2+
3+
#![crate_name = "foo"]
4+
5+
// @has 'foo/index.html'
6+
// Each compiler builtin proc-macro has a trait equivalent so we should have
7+
// a trait section as well.
8+
// @count - '//*[@id="main-content"]//*[@class="small-section-header"]' 2
9+
// @has - '//*[@id="main-content"]//*[@class="small-section-header"]' 'Traits'
10+
// @has - '//*[@id="main-content"]//*[@class="small-section-header"]' 'Derive Macros'
11+
12+
// Now checking the correct file is generated as well.
13+
// @has 'foo/derive.Clone.html'
14+
// @!has 'foo/macro.Clone.html'
15+
pub use std::clone::Clone;

tests/rustdoc/macro_pub_in_module.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,26 @@
77
#![crate_name = "krate"]
88
#![no_core]
99

10-
// @has external_crate/some_module/macro.external_macro.html
11-
// @!has external_crate/macro.external_macro.html
10+
// @has external_crate/some_module/macro.external_macro.html
11+
// @!has external_crate/macro.external_macro.html
1212
extern crate external_crate;
1313

1414
pub mod inner {
1515
// @has krate/inner/macro.raw_const.html
1616
// @!has krate/macro.raw_const.html
1717
pub macro raw_const() {}
1818

19-
// @has krate/inner/macro.test.html
19+
// @has krate/inner/attr.test.html
2020
// @!has krate/macro.test.html
21+
// @!has krate/inner/macro.test.html
22+
// @!has krate/attr.test.html
2123
#[rustc_builtin_macro]
2224
pub macro test($item:item) {}
2325

24-
// @has krate/inner/macro.Clone.html
26+
// @has krate/inner/derive.Clone.html
27+
// @!has krate/inner/macro.Clone.html
2528
// @!has krate/macro.Clone.html
29+
// @!has krate/derive.Clone.html
2630
#[rustc_builtin_macro]
2731
pub macro Clone($item:item) {}
2832

0 commit comments

Comments
 (0)