Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion 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_id(trait_ref.def_id(), cx.tcx);
if !matches!(kind, ItemType::Trait | ItemType::TraitAlias) {
span_bug!(cx.tcx.def_span(trait_ref.def_id()), "`TraitRef` had unexpected kind {kind:?}");
}
Expand Down
11 changes: 9 additions & 2 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,15 @@ impl Item {
debug!(?id);
if let Ok(HrefInfo { mut url, .. }) = href(*id, cx) {
debug!(?url);
if let Some(ref fragment) = *fragment {
fragment.render(&mut url, cx.tcx())
match fragment {
Some(UrlFragment::Item(def_id)) => {
url.push_str(&crate::html::format::fragment(*def_id, cx.tcx()))
}
Some(UrlFragment::UserWritten(raw)) => {
url.push('#');
url.push_str(raw);
}
None => {}
}
Some(RenderedLink {
original_text: s.clone(),
Expand Down
7 changes: 4 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 @@ -496,7 +497,7 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {

let (kind, did) = match res {
Res::Def(
kind @ (AssocTy
AssocTy
| AssocFn
| AssocConst
| Variant
Expand All @@ -511,9 +512,9 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
| Const
| Static { .. }
| Macro(..)
| TraitAlias),
| TraitAlias,
did,
) => (kind.into(), did),
) => (ItemType::from_def_id(did, cx.tcx), did),

_ => panic!("register_res: unexpected {res:?}"),
};
Expand Down
24 changes: 12 additions & 12 deletions src/librustdoc/formats/item_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use std::fmt;

use rustc_hir::def::{CtorOf, DefKind, MacroKinds};
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;
use rustc_span::hygiene::MacroKind;
use serde::{Deserialize, Deserializer, Serialize, Serializer, de};

Expand Down Expand Up @@ -147,17 +149,10 @@ impl<'a> From<&'a clean::Item> for ItemType {
}
}

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 {
match kind {
pub(crate) fn from_def_id(def_id: DefId, tcx: TyCtxt<'_>) -> Self {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that i think about it, wouldn't of_def_id be a more descriptive name?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not exactly seems it involves a type conversion, not a direct translation.

let def_kind = tcx.def_kind(def_id);
match def_kind {
DefKind::Enum => Self::Enum,
DefKind::Fn => Self::Function,
DefKind::Mod => Self::Module,
Expand All @@ -176,8 +171,13 @@ impl ItemType {
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::AssocFn => {
if tcx.associated_item(def_id).defaultness(tcx).has_value() {
Self::Method
} else {
Self::TyMethod
}
}
DefKind::Ctor(CtorOf::Struct, _) => Self::Struct,
DefKind::Ctor(CtorOf::Variant, _) => Self::Variant,
DefKind::AssocConst => Self::AssocConst,
Expand Down
45 changes: 26 additions & 19 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,6 @@ fn generate_item_def_id_path(
original_def_id: DefId,
cx: &Context<'_>,
root_path: Option<&str>,
original_def_kind: DefKind,
) -> Result<HrefInfo, HrefError> {
use rustc_middle::traits::ObligationCause;
use rustc_trait_selection::infer::TyCtxtInferExt;
Expand All @@ -457,15 +456,14 @@ fn generate_item_def_id_path(
let relative = clean::inline::item_relative_path(tcx, def_id);
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_id(def_id, tcx);
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_id(original_def_id, tcx);
url_parts = format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id))
};
Ok(HrefInfo { url: url_parts, kind: shortty, rust_path: fqp })
Expand Down Expand Up @@ -605,7 +603,7 @@ pub(crate) fn href_with_root_path(
} else if did.is_local() {
return Err(HrefError::Private);
} else {
return generate_item_def_id_path(did, original_did, cx, root_path, def_kind);
return generate_item_def_id_path(did, original_did, cx, root_path);
}
}
};
Expand Down Expand Up @@ -835,26 +833,35 @@ fn print_higher_ranked_params_with_space(
})
}

pub(crate) fn print_anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
if let Ok(HrefInfo { url, kind, rust_path }) = href(did, cx) {
let tcx = cx.tcx();
let def_kind = tcx.def_kind(did);
let anchor = if matches!(
def_kind,
DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant
) {
let parent_def_id = tcx.parent(did);
let item_type =
ItemType::from_def_kind(def_kind, Some(tcx.def_kind(parent_def_id)));
format!("#{}.{}", item_type.as_str(), tcx.item_name(did))
pub(crate) fn fragment(did: DefId, tcx: TyCtxt<'_>) -> String {
let def_kind = tcx.def_kind(did);
match def_kind {
DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => {
let item_type = ItemType::from_def_id(did, tcx);
format!("#{}.{}", item_type.as_str(), tcx.item_name(did))
}
DefKind::Field => {
let parent_def_id = tcx.parent(did);
let s;
let kind = if tcx.def_kind(parent_def_id) == DefKind::Variant {
s = format!("variant.{}.field", tcx.item_name(parent_def_id).as_str());
&s
} else {
String::new()
"structfield"
};
format!("#{kind}.{}", tcx.item_name(did))
}
_ => String::new(),
}
}

pub(crate) fn print_anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| {
if let Ok(HrefInfo { url, kind, rust_path }) = href(did, cx) {
write!(
f,
r#"<a class="{kind}" href="{url}{anchor}" title="{kind} {path}">{text}</a>"#,
anchor = fragment(did, cx.tcx()),
path = join_path_syms(rust_path),
text = EscapeBodyText(text.as_str()),
)
Expand Down
37 changes: 0 additions & 37 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,43 +203,6 @@ pub(crate) enum UrlFragment {
UserWritten(String),
}

impl UrlFragment {
/// Render the fragment, including the leading `#`.
pub(crate) fn render(&self, s: &mut String, tcx: TyCtxt<'_>) {
s.push('#');
match self {
&UrlFragment::Item(def_id) => {
let kind = match tcx.def_kind(def_id) {
DefKind::AssocFn => {
if tcx.associated_item(def_id).defaultness(tcx).has_value() {
"method."
} else {
"tymethod."
}
}
DefKind::AssocConst => "associatedconstant.",
DefKind::AssocTy => "associatedtype.",
DefKind::Variant => "variant.",
DefKind::Field => {
let parent_id = tcx.parent(def_id);
if tcx.def_kind(parent_id) == DefKind::Variant {
s.push_str("variant.");
s.push_str(tcx.item_name(parent_id).as_str());
".field."
} else {
"structfield."
}
}
kind => bug!("unexpected associated item kind: {kind:?}"),
};
s.push_str(kind);
s.push_str(tcx.item_name(def_id).as_str());
}
UrlFragment::UserWritten(raw) => s.push_str(raw),
}
}
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub(crate) struct ResolutionInfo {
item_id: DefId,
Expand Down
Loading