Skip to content

Commit ec20f2b

Browse files
Use ItemKind placeholders for alternative macro kinds
1 parent fe2f898 commit ec20f2b

File tree

14 files changed

+210
-153
lines changed

14 files changed

+210
-153
lines changed

src/librustdoc/clean/inline.rs

Lines changed: 74 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,27 @@ pub(crate) fn try_inline(
4646
attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
4747
visited: &mut DefIdSet,
4848
) -> Option<Vec<clean::Item>> {
49+
fn try_inline_inner(
50+
cx: &mut DocContext<'_>,
51+
kind: clean::ItemKind,
52+
did: DefId,
53+
name: Symbol,
54+
import_def_id: Option<LocalDefId>,
55+
) -> clean::Item {
56+
cx.inlined.insert(did.into());
57+
let mut item = crate::clean::generate_item_with_correct_attrs(
58+
cx,
59+
kind,
60+
did,
61+
name,
62+
import_def_id.as_slice(),
63+
None,
64+
);
65+
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
66+
item.inner.inline_stmt_id = import_def_id;
67+
item
68+
}
69+
4970
let did = res.opt_def_id()?;
5071
if did.is_local() {
5172
return None;
@@ -138,7 +159,7 @@ pub(crate) fn try_inline(
138159
})
139160
}
140161
Res::Def(DefKind::Macro(kinds), did) => {
141-
let mac = build_macro(cx, did, name, kinds);
162+
let (mac, others) = build_macro(cx, did, name, kinds);
142163

143164
let type_kind = match kinds {
144165
MacroKinds::BANG => ItemType::Macro,
@@ -148,23 +169,21 @@ pub(crate) fn try_inline(
148169
_ => panic!("unsupported macro kind {kinds:?}"),
149170
};
150171
record_extern_fqn(cx, did, type_kind);
151-
mac
172+
let first = try_inline_inner(cx, mac, did, name, import_def_id);
173+
if let Some(others) = others {
174+
for mac_kind in others {
175+
let mut mac = first.clone();
176+
mac.inner.kind = mac_kind;
177+
ret.push(mac);
178+
}
179+
}
180+
ret.push(first);
181+
return Some(ret);
152182
}
153183
_ => return None,
154184
};
155185

156-
cx.inlined.insert(did.into());
157-
let mut item = crate::clean::generate_item_with_correct_attrs(
158-
cx,
159-
kind,
160-
did,
161-
name,
162-
import_def_id.as_slice(),
163-
None,
164-
);
165-
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
166-
item.inner.inline_stmt_id = import_def_id;
167-
ret.push(item);
186+
ret.push(try_inline_inner(cx, kind, did, name, import_def_id));
168187
Some(ret)
169188
}
170189

@@ -752,31 +771,51 @@ fn build_macro(
752771
def_id: DefId,
753772
name: Symbol,
754773
macro_kinds: MacroKinds,
755-
) -> clean::ItemKind {
774+
) -> (clean::ItemKind, Option<Vec<clean::ItemKind>>) {
756775
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) {
757776
LoadedMacro::MacroDef { def, .. } => match macro_kinds {
758-
MacroKinds::BANG => clean::MacroItem(
759-
clean::Macro {
760-
source: utils::display_macro_source(cx, name, &def),
761-
macro_rules: def.macro_rules,
762-
},
777+
MacroKinds::BANG => (
778+
clean::MacroItem(
779+
clean::Macro {
780+
source: utils::display_macro_source(cx, name, &def),
781+
macro_rules: def.macro_rules,
782+
},
783+
None,
784+
),
785+
None,
786+
),
787+
MacroKinds::DERIVE => (
788+
clean::ProcMacroItem(clean::ProcMacro {
789+
kind: MacroKind::Derive,
790+
helpers: Vec::new(),
791+
}),
763792
None,
764793
),
765-
MacroKinds::DERIVE => clean::ProcMacroItem(clean::ProcMacro {
766-
kind: MacroKind::Derive,
767-
helpers: Vec::new(),
768-
}),
769-
MacroKinds::ATTR => clean::ProcMacroItem(clean::ProcMacro {
770-
kind: MacroKind::Attr,
771-
helpers: Vec::new(),
772-
}),
773-
_ if macro_kinds == (MacroKinds::BANG | MacroKinds::ATTR) => clean::MacroItem(
774-
clean::Macro {
775-
source: utils::display_macro_source(cx, name, &def),
776-
macro_rules: def.macro_rules,
777-
},
778-
Some(macro_kinds),
794+
MacroKinds::ATTR => (
795+
clean::ProcMacroItem(clean::ProcMacro {
796+
kind: MacroKind::Attr,
797+
helpers: Vec::new(),
798+
}),
799+
None,
779800
),
801+
_ if macro_kinds.contains(MacroKinds::BANG) => {
802+
let kind = clean::MacroItem(
803+
clean::Macro {
804+
source: utils::display_macro_source(cx, name, &def),
805+
macro_rules: def.macro_rules,
806+
},
807+
Some(macro_kinds),
808+
);
809+
let mut ret = vec![];
810+
for kind in macro_kinds.iter().filter(|kind| *kind != MacroKinds::BANG) {
811+
match kind {
812+
MacroKinds::ATTR => ret.push(clean::AttrMacroItem),
813+
MacroKinds::DERIVE => ret.push(clean::DeriveMacroItem),
814+
_ => panic!("unsupported macro kind {kind:?}"),
815+
}
816+
}
817+
(kind, Some(ret))
818+
}
780819
_ => panic!("unsupported macro kind {macro_kinds:?}"),
781820
},
782821
LoadedMacro::ProcMacro(ext) => {
@@ -787,7 +826,7 @@ fn build_macro(
787826
MacroKinds::DERIVE => MacroKind::Derive,
788827
_ => unreachable!(),
789828
};
790-
clean::ProcMacroItem(clean::ProcMacro { kind, helpers: ext.helper_attrs })
829+
(clean::ProcMacroItem(clean::ProcMacro { kind, helpers: ext.helper_attrs }), None)
791830
}
792831
}
793832
}

src/librustdoc/clean/mod.rs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2853,13 +2853,43 @@ fn clean_maybe_renamed_item<'tcx>(
28532853
),
28542854
MacroKinds::ATTR => clean_proc_macro(item, &mut name, MacroKind::Attr, cx),
28552855
MacroKinds::DERIVE => clean_proc_macro(item, &mut name, MacroKind::Derive, cx),
2856-
_ => MacroItem(
2857-
Macro {
2858-
source: display_macro_source(cx, name, macro_def),
2859-
macro_rules: macro_def.macro_rules,
2860-
},
2861-
Some(kinds),
2862-
),
2856+
_ if kinds.contains(MacroKinds::BANG) => {
2857+
let kind = MacroItem(
2858+
Macro {
2859+
source: display_macro_source(cx, name, macro_def),
2860+
macro_rules: macro_def.macro_rules,
2861+
},
2862+
Some(kinds),
2863+
);
2864+
let mac = generate_item_with_correct_attrs(
2865+
cx,
2866+
kind,
2867+
item.owner_id.def_id.to_def_id(),
2868+
name,
2869+
import_ids,
2870+
renamed,
2871+
);
2872+
2873+
let mut ret = Vec::with_capacity(3);
2874+
for kind in kinds.iter().filter(|kind| *kind != MacroKinds::BANG) {
2875+
match kind {
2876+
MacroKinds::ATTR => {
2877+
let mut attr = mac.clone();
2878+
attr.inner.kind = AttrMacroItem;
2879+
ret.push(attr);
2880+
}
2881+
MacroKinds::DERIVE => {
2882+
let mut derive = mac.clone();
2883+
derive.inner.kind = DeriveMacroItem;
2884+
ret.push(derive);
2885+
}
2886+
_ => panic!("unsupported macro kind {kind:?}"),
2887+
}
2888+
}
2889+
ret.push(mac);
2890+
return ret;
2891+
}
2892+
_ => panic!("unsupported macro kind {kinds:?}"),
28632893
},
28642894
// proc macros can have a name set by attributes
28652895
ItemKind::Fn { ref sig, generics, body: body_id, .. } => {

src/librustdoc/clean/types.rs

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -664,29 +664,23 @@ impl Item {
664664
find_attr!(&self.attrs.other_attrs, AttributeKind::NonExhaustive(..))
665665
}
666666

667-
pub(crate) fn bang_macro_types(&self) -> Option<Vec<ItemType>> {
668-
match self.kind {
669-
ItemKind::MacroItem(_, None) => Some(vec![ItemType::Macro]),
670-
ItemKind::MacroItem(_, Some(kinds)) => Some(
671-
kinds
672-
.iter()
673-
.map(|kind| match kind {
674-
MacroKinds::BANG => ItemType::Macro,
675-
MacroKinds::ATTR => ItemType::ProcAttribute,
676-
MacroKinds::DERIVE => ItemType::ProcDerive,
677-
_ => panic!("unexpected macro kind {kind:?}"),
678-
})
679-
.collect::<Vec<_>>(),
680-
),
681-
_ => None,
682-
}
683-
}
684-
685667
/// Returns a documentation-level item type from the item.
686668
pub(crate) fn type_(&self) -> ItemType {
687669
ItemType::from(self)
688670
}
689671

672+
/// Generates the HTML file name based on the item kind.
673+
pub(crate) fn html_filename(&self) -> String {
674+
let type_ = if self.is_macro_placeholder() { ItemType::Macro } else { self.type_() };
675+
format!("{type_}.{}.html", self.name.unwrap())
676+
}
677+
678+
/// If the current item is a "fake" macro (ie, `AttrMacroItem | ItemKind::DeriveMacroItem` which
679+
/// don't hold any data), it returns `true`.
680+
pub(crate) fn is_macro_placeholder(&self) -> bool {
681+
matches!(self.kind, ItemKind::AttrMacroItem | ItemKind::DeriveMacroItem)
682+
}
683+
690684
pub(crate) fn is_default(&self) -> bool {
691685
match self.kind {
692686
ItemKind::MethodItem(_, Some(defaultness)) => {
@@ -972,6 +966,8 @@ pub(crate) enum ItemKind {
972966
/// `type`s from an extern block
973967
ForeignTypeItem,
974968
MacroItem(Macro, Option<MacroKinds>),
969+
AttrMacroItem,
970+
DeriveMacroItem,
975971
ProcMacroItem(ProcMacro),
976972
PrimitiveItem(PrimitiveType),
977973
/// A required associated constant in a trait declaration.
@@ -1027,6 +1023,8 @@ impl ItemKind {
10271023
| ForeignStaticItem(_, _)
10281024
| ForeignTypeItem
10291025
| MacroItem(..)
1026+
| AttrMacroItem
1027+
| DeriveMacroItem
10301028
| ProcMacroItem(_)
10311029
| PrimitiveItem(_)
10321030
| RequiredAssocConstItem(..)

src/librustdoc/fold.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ pub(crate) trait DocFolder: Sized {
8989
| ForeignStaticItem(..)
9090
| ForeignTypeItem
9191
| MacroItem(..)
92+
| AttrMacroItem
93+
| DeriveMacroItem
9294
| ProcMacroItem(_)
9395
| PrimitiveItem(_)
9496
| RequiredAssocConstItem(..)

src/librustdoc/formats/cache.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,10 @@ impl DocFolder for CacheBuilder<'_, '_> {
372372
| clean::RequiredAssocTypeItem(..)
373373
| clean::AssocTypeItem(..)
374374
| clean::StrippedItem(..)
375-
| clean::KeywordItem
376-
| clean::AttributeItem => {
375+
| clean::AttributeItem
376+
| clean::AttrMacroItem
377+
| clean::DeriveMacroItem
378+
| clean::KeywordItem => {
377379
// FIXME: Do these need handling?
378380
// The person writing this comment doesn't know.
379381
// So would rather leave them to an expert,

src/librustdoc/formats/item_type.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ impl<'a> From<&'a clean::Item> for ItemType {
128128
clean::ForeignFunctionItem(..) => ItemType::Function, // no ForeignFunction
129129
clean::ForeignStaticItem(..) => ItemType::Static, // no ForeignStatic
130130
clean::MacroItem(..) => ItemType::Macro,
131+
// Is this a good idea?
132+
clean::AttrMacroItem => ItemType::ProcAttribute,
133+
// Is this a good idea?
134+
clean::DeriveMacroItem => ItemType::ProcDerive,
131135
clean::PrimitiveItem(..) => ItemType::Primitive,
132136
clean::RequiredAssocConstItem(..)
133137
| clean::ProvidedAssocConstItem(..)

0 commit comments

Comments
 (0)