Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 80 additions & 34 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,27 @@ pub(crate) fn try_inline(
attrs: Option<(&[hir::Attribute], Option<LocalDefId>)>,
visited: &mut DefIdSet,
) -> Option<Vec<clean::Item>> {
fn try_inline_inner(
cx: &mut DocContext<'_>,
kind: clean::ItemKind,
did: DefId,
name: Symbol,
import_def_id: Option<LocalDefId>,
) -> clean::Item {
cx.inlined.insert(did.into());
let mut item = crate::clean::generate_item_with_correct_attrs(
cx,
kind,
did,
name,
import_def_id.as_slice(),
None,
);
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
item.inner.inline_stmt_id = import_def_id;
item
}

let did = res.opt_def_id()?;
if did.is_local() {
return None;
Expand Down Expand Up @@ -138,34 +159,31 @@ pub(crate) fn try_inline(
})
}
Res::Def(DefKind::Macro(kinds), did) => {
let mac = build_macro(cx, did, name, kinds);
let (mac, others) = build_macro(cx, did, name, kinds);

// FIXME: handle attributes and derives that aren't proc macros, and macros with
// multiple kinds
let type_kind = match kinds {
MacroKinds::BANG => ItemType::Macro,
MacroKinds::ATTR => ItemType::ProcAttribute,
MacroKinds::DERIVE => ItemType::ProcDerive,
_ => todo!("Handle macros with multiple kinds"),
// Then it means it's more than one type so we default to "macro".
_ => ItemType::Macro,
};
record_extern_fqn(cx, did, type_kind);
mac
let first = try_inline_inner(cx, mac, did, name, import_def_id);
if let Some(others) = others {
for mac_kind in others {
let mut mac = first.clone();
mac.inner.kind = mac_kind;
ret.push(mac);
}
}
ret.push(first);
return Some(ret);
}
_ => return None,
};

cx.inlined.insert(did.into());
let mut item = crate::clean::generate_item_with_correct_attrs(
cx,
kind,
did,
name,
import_def_id.as_slice(),
None,
);
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
item.inner.inline_stmt_id = import_def_id;
ret.push(item);
ret.push(try_inline_inner(cx, kind, did, name, import_def_id));
Some(ret)
}

Expand Down Expand Up @@ -774,24 +792,52 @@ fn build_macro(
def_id: DefId,
name: Symbol,
macro_kinds: MacroKinds,
) -> clean::ItemKind {
) -> (clean::ItemKind, Option<Vec<clean::ItemKind>>) {
match CStore::from_tcx(cx.tcx).load_macro_untracked(cx.tcx, def_id) {
// FIXME: handle attributes and derives that aren't proc macros, and macros with multiple
// kinds
LoadedMacro::MacroDef { def, .. } => match macro_kinds {
MacroKinds::BANG => clean::MacroItem(clean::Macro {
source: utils::display_macro_source(cx, name, &def),
macro_rules: def.macro_rules,
}),
MacroKinds::DERIVE => clean::ProcMacroItem(clean::ProcMacro {
kind: MacroKind::Derive,
helpers: Vec::new(),
}),
MacroKinds::ATTR => clean::ProcMacroItem(clean::ProcMacro {
kind: MacroKind::Attr,
helpers: Vec::new(),
}),
_ => todo!("Handle macros with multiple kinds"),
MacroKinds::BANG => (
clean::MacroItem(
clean::Macro {
source: utils::display_macro_source(cx, name, &def),
macro_rules: def.macro_rules,
},
MacroKinds::BANG,
),
None,
),
MacroKinds::DERIVE => (
clean::ProcMacroItem(clean::ProcMacro {
kind: MacroKind::Derive,
helpers: Vec::new(),
}),
None,
),
MacroKinds::ATTR => (
clean::ProcMacroItem(clean::ProcMacro {
kind: MacroKind::Attr,
helpers: Vec::new(),
}),
None,
),
_ => {
let mut kinds = Vec::new();
kinds.push(clean::MacroItem(
clean::Macro {
source: utils::display_macro_source(cx, name, &def),
macro_rules: def.macro_rules,
},
macro_kinds,
));
for kind in macro_kinds.iter().filter(|kind| *kind != MacroKinds::BANG) {
match kind {
MacroKinds::ATTR => kinds.push(clean::AttrMacroItem),
MacroKinds::DERIVE => kinds.push(clean::DeriveMacroItem),
_ => panic!("unsupported macro kind {kind:?}"),
}
}
let kind = kinds.pop().expect("no supported macro kind found");
(kind, Some(kinds))
}
},
LoadedMacro::ProcMacro(ext) => {
// Proc macros can only have a single kind
Expand All @@ -801,7 +847,7 @@ fn build_macro(
MacroKinds::DERIVE => MacroKind::Derive,
_ => unreachable!(),
};
clean::ProcMacroItem(clean::ProcMacro { kind, helpers: ext.helper_attrs })
(clean::ProcMacroItem(clean::ProcMacro { kind, helpers: ext.helper_attrs }), None)
}
}
}
Expand Down
60 changes: 47 additions & 13 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2821,19 +2821,53 @@ fn clean_maybe_renamed_item<'tcx>(
generics: clean_generics(generics, cx),
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}),
// FIXME: handle attributes and derives that aren't proc macros, and macros with
// multiple kinds
ItemKind::Macro(_, macro_def, MacroKinds::BANG) => MacroItem(Macro {
source: display_macro_source(cx, name, macro_def),
macro_rules: macro_def.macro_rules,
}),
ItemKind::Macro(_, _, MacroKinds::ATTR) => {
clean_proc_macro(item, &mut name, MacroKind::Attr, cx)
}
ItemKind::Macro(_, _, MacroKinds::DERIVE) => {
clean_proc_macro(item, &mut name, MacroKind::Derive, cx)
}
ItemKind::Macro(_, _, _) => todo!("Handle macros with multiple kinds"),
ItemKind::Macro(_, macro_def, kinds) => match kinds {
MacroKinds::BANG => MacroItem(
Macro {
source: display_macro_source(cx, name, macro_def),
macro_rules: macro_def.macro_rules,
},
MacroKinds::BANG,
),
MacroKinds::ATTR => clean_proc_macro(item, &mut name, MacroKind::Attr, cx),
MacroKinds::DERIVE => clean_proc_macro(item, &mut name, MacroKind::Derive, cx),
_ => {
let kind = MacroItem(
Macro {
source: display_macro_source(cx, name, macro_def),
macro_rules: macro_def.macro_rules,
},
kinds,
);
let mac = generate_item_with_correct_attrs(
cx,
kind,
item.owner_id.def_id.to_def_id(),
name,
import_ids,
renamed,
);

let mut ret = Vec::with_capacity(3);
for kind in kinds.iter().filter(|kind| *kind != MacroKinds::BANG) {
match kind {
MacroKinds::ATTR => {
let mut attr = mac.clone();
attr.inner.kind = AttrMacroItem;
ret.push(attr);
}
MacroKinds::DERIVE => {
let mut derive = mac.clone();
derive.inner.kind = DeriveMacroItem;
ret.push(derive);
}
_ => panic!("unsupported macro kind {kind:?}"),
}
}
ret.push(mac);
return ret;
}
},
// proc macros can have a name set by attributes
ItemKind::Fn { ref sig, generics, body: body_id, .. } => {
clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
Expand Down
26 changes: 23 additions & 3 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rustc_ast::attr::AttributeExt;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::thin_vec::ThinVec;
use rustc_hir::attrs::{AttributeKind, DeprecatedSince, Deprecation, DocAttribute};
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def::{CtorKind, DefKind, MacroKinds, Res};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{Attribute, BodyId, ConstStability, Mutability, Stability, StableSince, find_attr};
Expand Down Expand Up @@ -703,6 +703,18 @@ impl Item {
ItemType::from(self)
}

/// Generates the HTML file name based on the item kind.
pub(crate) fn html_filename(&self) -> String {
let type_ = if self.is_macro_placeholder() { ItemType::Macro } else { self.type_() };
format!("{type_}.{}.html", self.name.unwrap())
}

/// If the current item is a "fake" macro (ie, `AttrMacroItem | ItemKind::DeriveMacroItem` which
/// don't hold any data), it returns `true`.
pub(crate) fn is_macro_placeholder(&self) -> bool {
matches!(self.kind, ItemKind::AttrMacroItem | ItemKind::DeriveMacroItem)
}

pub(crate) fn is_default(&self) -> bool {
match self.kind {
ItemKind::MethodItem(_, Some(defaultness)) => {
Expand Down Expand Up @@ -868,7 +880,13 @@ pub(crate) enum ItemKind {
ForeignStaticItem(Static, hir::Safety),
/// `type`s from an extern block
ForeignTypeItem,
MacroItem(Macro),
MacroItem(Macro, MacroKinds),
/// This is NOT an attribute proc-macro but a bang macro with support for being used as an
/// attribute macro.
AttrMacroItem,
/// This is NOT an attribute proc-macro but a bang macro with support for being used as a
/// derive macro.
DeriveMacroItem,
ProcMacroItem(ProcMacro),
PrimitiveItem(PrimitiveType),
/// A required associated constant in a trait declaration.
Expand Down Expand Up @@ -923,7 +941,9 @@ impl ItemKind {
| ForeignFunctionItem(_, _)
| ForeignStaticItem(_, _)
| ForeignTypeItem
| MacroItem(_)
| MacroItem(..)
| AttrMacroItem
| DeriveMacroItem
| ProcMacroItem(_)
| PrimitiveItem(_)
| RequiredAssocConstItem(..)
Expand Down
4 changes: 3 additions & 1 deletion src/librustdoc/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,9 @@ pub(crate) trait DocFolder: Sized {
| ForeignFunctionItem(..)
| ForeignStaticItem(..)
| ForeignTypeItem
| MacroItem(_)
| MacroItem(..)
| AttrMacroItem
| DeriveMacroItem
| ProcMacroItem(_)
| PrimitiveItem(_)
| RequiredAssocConstItem(..)
Expand Down
8 changes: 6 additions & 2 deletions src/librustdoc/formats/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::mem;

use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir::StabilityLevel;
use rustc_hir::def::MacroKinds;
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet};
use rustc_metadata::creader::CStore;
use rustc_middle::ty::{self, TyCtxt};
Expand Down Expand Up @@ -382,8 +383,10 @@ impl DocFolder for CacheBuilder<'_, '_> {
| clean::RequiredAssocTypeItem(..)
| clean::AssocTypeItem(..)
| clean::StrippedItem(..)
| clean::KeywordItem
| clean::AttributeItem => {
| clean::AttributeItem
| clean::AttrMacroItem
| clean::DeriveMacroItem
| clean::KeywordItem => {
// FIXME: Do these need handling?
// The person writing this comment doesn't know.
// So would rather leave them to an expert,
Expand Down Expand Up @@ -484,6 +487,7 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
// Item has a name, so it must also have a DefId (can't be an impl, let alone a blanket or auto impl).
let item_def_id = item.item_id.as_def_id().unwrap();
let (parent_did, parent_path) = match item.kind {
clean::MacroItem(_, kinds) if !kinds.contains(MacroKinds::BANG) => return,
clean::StrippedItem(..) => return,
clean::ProvidedAssocConstItem(..)
| clean::ImplAssocConstItem(..)
Expand Down
8 changes: 6 additions & 2 deletions src/librustdoc/formats/item_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ item_type! {
// This number is reserved for use in JavaScript
// Generic = 26,
Attribute = 27,
BangMacroAttribute = 28,
BangMacroDerive = 29,
}

impl<'a> From<&'a clean::Item> for ItemType {
Expand Down Expand Up @@ -130,6 +132,8 @@ impl<'a> From<&'a clean::Item> for ItemType {
clean::ForeignFunctionItem(..) => ItemType::Function, // no ForeignFunction
clean::ForeignStaticItem(..) => ItemType::Static, // no ForeignStatic
clean::MacroItem(..) => ItemType::Macro,
clean::AttrMacroItem => ItemType::BangMacroAttribute,
clean::DeriveMacroItem => ItemType::BangMacroDerive,
clean::PrimitiveItem(..) => ItemType::Primitive,
clean::RequiredAssocConstItem(..)
| clean::ProvidedAssocConstItem(..)
Expand Down Expand Up @@ -221,8 +225,8 @@ impl ItemType {
ItemType::AssocConst => "associatedconstant",
ItemType::ForeignType => "foreigntype",
ItemType::Keyword => "keyword",
ItemType::ProcAttribute => "attr",
ItemType::ProcDerive => "derive",
ItemType::ProcAttribute | ItemType::BangMacroAttribute => "attr",
ItemType::ProcDerive | ItemType::BangMacroDerive => "derive",
ItemType::TraitAlias => "traitalias",
ItemType::Attribute => "attribute",
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2054,7 +2054,7 @@ fn is_default_id(id: &str) -> bool {
| "crate-search"
| "crate-search-div"
// This is the list of IDs used in HTML generated in Rust (including the ones
// used in tera template files).
// used in askama template files).
| "themeStyle"
| "settings-menu"
| "help-button"
Expand Down Expand Up @@ -2093,7 +2093,7 @@ fn is_default_id(id: &str) -> bool {
| "blanket-implementations-list"
| "deref-methods"
| "layout"
| "aliased-type"
| "aliased-type",
)
}

Expand Down
Loading
Loading