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
96 changes: 54 additions & 42 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,37 @@ pub(crate) fn try_inline(
})
}
Res::Def(DefKind::Macro(kinds), did) => {
let mac = 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"),
};
record_extern_fqn(cx, did, type_kind);
mac
for mac_kind in kinds {
let kind = build_macro(
cx,
did,
name,
match mac_kind {
MacroKinds::BANG => MacroKind::Bang,
MacroKinds::ATTR => MacroKind::Attr,
MacroKinds::DERIVE => MacroKind::Derive,
_ => unreachable!(
"Iterating over macro kinds always yields one kind at a time"
),
},
);
let type_kind = match mac_kind {
MacroKinds::BANG => ItemType::Macro,
MacroKinds::ATTR => ItemType::MacroAttribute,
MacroKinds::DERIVE => ItemType::MacroDerive,
_ => {
unreachable!("Iterating over macro kinds always yields one kind at a time")
}
};
record_extern_fqn(cx, did, type_kind);
ret.push(try_inline_inner(cx, kind, did, name, import_def_id));
}
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 @@ -761,26 +785,14 @@ fn build_macro(
cx: &mut DocContext<'_>,
def_id: DefId,
name: Symbol,
macro_kinds: MacroKinds,
kind: MacroKind,
) -> clean::ItemKind {
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) {
// 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"),
},
LoadedMacro::MacroDef { def, .. } => clean::MacroItem(clean::Macro {
source: utils::display_macro_source(cx, name, &def),
macro_rules: def.macro_rules,
kind,
}),
LoadedMacro::ProcMacro(ext) => {
// Proc macros can only have a single kind
let kind = match ext.macro_kinds() {
Expand Down
40 changes: 27 additions & 13 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ pub(crate) fn clean_trait_ref_with_constraints<'tcx>(
trait_ref: ty::PolyTraitRef<'tcx>,
constraints: ThinVec<AssocItemConstraint>,
) -> Path {
let kind = cx.tcx.def_kind(trait_ref.def_id()).into();
let kind = ItemType::from_def_kind(cx.tcx.def_kind(trait_ref.def_id()), None)[0];
if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
span_bug!(cx.tcx.def_span(trait_ref.def_id()), "`TraitRef` had unexpected kind {kind:?}");
}
Expand Down Expand Up @@ -2841,19 +2841,33 @@ 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(_, macro_def, macro_kinds) => {
return macro_kinds
.into_iter()
.map(|macro_kind| {
let kind = MacroItem(Macro {
source: display_macro_source(cx, name, macro_def),
macro_rules: macro_def.macro_rules,
kind: match macro_kind {
MacroKinds::BANG => MacroKind::Bang,
MacroKinds::ATTR => MacroKind::Attr,
MacroKinds::DERIVE => MacroKind::Derive,
_ => unreachable!(
"Iterating over macro kinds always yields one kind at a time"
),
},
});
generate_item_with_correct_attrs(
cx,
kind,
item.owner_id.def_id.to_def_id(),
name,
import_ids,
renamed,
)
})
.collect();
}
ItemKind::Macro(_, _, _) => todo!("Handle macros with multiple kinds"),
// 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
1 change: 1 addition & 0 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2367,6 +2367,7 @@ pub(crate) struct Macro {
pub(crate) source: String,
/// Whether the macro was defined via `macro_rules!` as opposed to `macro`.
pub(crate) macro_rules: bool,
pub(crate) kind: MacroKind,
}

#[derive(Clone, Debug)]
Expand Down
9 changes: 6 additions & 3 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::clean::{
};
use crate::core::DocContext;
use crate::display::Joined as _;
use crate::formats::item_type::ItemType;

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -495,7 +496,7 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
use DefKind::*;
debug!("register_res({res:?})");

let (kind, did) = match res {
let (kinds, did) = match res {
Res::Def(
kind @ (AssocTy
| AssocFn
Expand All @@ -514,14 +515,16 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
| Macro(..)
| TraitAlias),
did,
) => (kind.into(), did),
) => (ItemType::from_def_kind(kind, None), did),

_ => panic!("register_res: unexpected {res:?}"),
};
if did.is_local() {
return did;
}
inline::record_extern_fqn(cx, did, kind);
for kind in kinds.iter().copied() {
inline::record_extern_fqn(cx, did, kind);
}
did
}

Expand Down
88 changes: 50 additions & 38 deletions src/librustdoc/formats/item_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ item_type! {
Union = 20,
ForeignType = 21,
// OpaqueTy used to be here, but it was removed in #127276
ProcAttribute = 23,
ProcDerive = 24,
MacroAttribute = 23,
MacroDerive = 24,
TraitAlias = 25,
// This number is reserved for use in JavaScript
// Generic = 26,
Expand Down Expand Up @@ -127,7 +127,11 @@ impl<'a> From<&'a clean::Item> for ItemType {
clean::VariantItem(..) => ItemType::Variant,
clean::ForeignFunctionItem(..) => ItemType::Function, // no ForeignFunction
clean::ForeignStaticItem(..) => ItemType::Static, // no ForeignStatic
clean::MacroItem(..) => ItemType::Macro,
clean::MacroItem(mac) => match mac.kind {
MacroKind::Bang => ItemType::Macro,
MacroKind::Attr => ItemType::MacroAttribute,
MacroKind::Derive => ItemType::MacroDerive,
},
clean::PrimitiveItem(..) => ItemType::Primitive,
clean::RequiredAssocConstItem(..)
| clean::ProvidedAssocConstItem(..)
Expand All @@ -139,48 +143,56 @@ impl<'a> From<&'a clean::Item> for ItemType {
clean::TraitAliasItem(..) => ItemType::TraitAlias,
clean::ProcMacroItem(mac) => match mac.kind {
MacroKind::Bang => ItemType::Macro,
MacroKind::Attr => ItemType::ProcAttribute,
MacroKind::Derive => ItemType::ProcDerive,
MacroKind::Attr => ItemType::MacroAttribute,
MacroKind::Derive => ItemType::MacroDerive,
},
clean::StrippedItem(..) => unreachable!(),
}
}
}

impl From<DefKind> for ItemType {
fn from(other: DefKind) -> Self {
Self::from_def_kind(other, None)
}
}

impl ItemType {
/// Depending on the parent kind, some variants have a different translation (like a `Method`
/// becoming a `TyMethod`).
pub(crate) fn from_def_kind(kind: DefKind, parent_kind: Option<DefKind>) -> Self {
pub(crate) fn from_def_kind(kind: DefKind, parent_kind: Option<DefKind>) -> &'static [Self] {
match kind {
DefKind::Enum => Self::Enum,
DefKind::Fn => Self::Function,
DefKind::Mod => Self::Module,
DefKind::Const => Self::Constant,
DefKind::Static { .. } => Self::Static,
DefKind::Struct => Self::Struct,
DefKind::Union => Self::Union,
DefKind::Trait => Self::Trait,
DefKind::TyAlias => Self::TypeAlias,
DefKind::TraitAlias => Self::TraitAlias,
DefKind::Macro(MacroKinds::BANG) => ItemType::Macro,
DefKind::Macro(MacroKinds::ATTR) => ItemType::ProcAttribute,
DefKind::Macro(MacroKinds::DERIVE) => ItemType::ProcDerive,
DefKind::Macro(_) => todo!("Handle macros with multiple kinds"),
DefKind::ForeignTy => Self::ForeignType,
DefKind::Variant => Self::Variant,
DefKind::Field => Self::StructField,
DefKind::AssocTy => Self::AssocType,
DefKind::AssocFn if let Some(DefKind::Trait) = parent_kind => Self::TyMethod,
DefKind::AssocFn => Self::Method,
DefKind::Ctor(CtorOf::Struct, _) => Self::Struct,
DefKind::Ctor(CtorOf::Variant, _) => Self::Variant,
DefKind::AssocConst => Self::AssocConst,
DefKind::Enum => &[Self::Enum],
DefKind::Fn => &[Self::Function],
DefKind::Mod => &[Self::Module],
DefKind::Const => &[Self::Constant],
DefKind::Static { .. } => &[Self::Static],
DefKind::Struct => &[Self::Struct],
DefKind::Union => &[Self::Union],
DefKind::Trait => &[Self::Trait],
DefKind::TyAlias => &[Self::TypeAlias],
DefKind::TraitAlias => &[Self::TraitAlias],
DefKind::Macro(MacroKinds::ATTR) => &[ItemType::MacroAttribute],
DefKind::Macro(MacroKinds::DERIVE) => &[ItemType::MacroDerive],
DefKind::Macro(MacroKinds::BANG) => &[ItemType::Macro],
DefKind::Macro(kinds) if kinds == MacroKinds::ATTR | MacroKinds::DERIVE => {
&[ItemType::MacroAttribute, ItemType::MacroDerive]
}
DefKind::Macro(kinds) if kinds == MacroKinds::ATTR | MacroKinds::BANG => {
&[ItemType::Macro, ItemType::MacroAttribute]
}
DefKind::Macro(kinds) if kinds == MacroKinds::DERIVE | MacroKinds::BANG => {
&[ItemType::Macro, ItemType::MacroDerive]
}
DefKind::Macro(kinds)
if kinds == MacroKinds::BANG | MacroKinds::ATTR | MacroKinds::DERIVE =>
{
&[ItemType::Macro, ItemType::MacroAttribute, ItemType::MacroDerive]
}
DefKind::Macro(kinds) => unimplemented!("unsupported macro kinds {kinds:?}"),
DefKind::ForeignTy => &[Self::ForeignType],
DefKind::Variant => &[Self::Variant],
DefKind::Field => &[Self::StructField],
DefKind::AssocTy => &[Self::AssocType],
DefKind::AssocFn if let Some(DefKind::Trait) = parent_kind => &[Self::TyMethod],
DefKind::AssocFn => &[Self::Method],
DefKind::Ctor(CtorOf::Struct, _) => &[Self::Struct],
DefKind::Ctor(CtorOf::Variant, _) => &[Self::Variant],
DefKind::AssocConst => &[Self::AssocConst],
DefKind::TyParam
| DefKind::ConstParam
| DefKind::ExternCrate
Expand All @@ -193,7 +205,7 @@ impl ItemType {
| DefKind::GlobalAsm
| DefKind::Impl { .. }
| DefKind::Closure
| DefKind::SyntheticCoroutineBody => Self::ForeignType,
| DefKind::SyntheticCoroutineBody => &[Self::ForeignType],
}
}

Expand Down Expand Up @@ -221,8 +233,8 @@ impl ItemType {
ItemType::AssocConst => "associatedconstant",
ItemType::ForeignType => "foreigntype",
ItemType::Keyword => "keyword",
ItemType::ProcAttribute => "attr",
ItemType::ProcDerive => "derive",
ItemType::MacroAttribute => "attr",
ItemType::MacroDerive => "derive",
ItemType::TraitAlias => "traitalias",
ItemType::Attribute => "attribute",
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,14 +443,14 @@ fn generate_item_def_id_path(
let fqp: Vec<Symbol> = once(crate_name).chain(relative).collect();

let def_kind = tcx.def_kind(def_id);
let shortty = def_kind.into();
let shortty = ItemType::from_def_kind(def_kind, None)[0];
let module_fqp = to_module_fqp(shortty, &fqp);
let mut is_remote = false;

let url_parts = url_parts(cx.cache(), def_id, module_fqp, &cx.current, &mut is_remote)?;
let mut url_parts = make_href(root_path, shortty, url_parts, &fqp, is_remote);
if def_id != original_def_id {
let kind = ItemType::from_def_kind(original_def_kind, Some(def_kind));
let kind = ItemType::from_def_kind(original_def_kind, Some(def_kind))[0];
url_parts = format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id))
};
Ok((url_parts, shortty, fqp))
Expand Down
Loading
Loading