Rollup merge of #149028 - GuillaumeGomez:unify-anchor, r=lolbinarycat
[rustdoc] Remove `UrlFragment::render` method to unify `clean::types::links` and `anchor` Fixes https://github.com/rust-lang/rust/issues/148648. First part of https://github.com/rust-lang/rust/issues/148547. The last part will be about handle `AssocItemLink` differently (either remove it or change how we do it). r? `@lolbinarycat`
This commit is contained in:
commit
110471b229
6 changed files with 55 additions and 74 deletions
|
|
@ -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:?}");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::fmt::Write;
|
||||
use std::hash::Hash;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, OnceLock as OnceCell};
|
||||
|
|
@ -522,8 +523,16 @@ 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)) => {
|
||||
write!(url, "{}", crate::html::format::fragment(*def_id, cx.tcx()))
|
||||
.unwrap();
|
||||
}
|
||||
Some(UrlFragment::UserWritten(raw)) => {
|
||||
url.push('#');
|
||||
url.push_str(raw);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
Some(RenderedLink {
|
||||
original_text: s.clone(),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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:?}"),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
||||
|
|
@ -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 {
|
||||
let def_kind = tcx.def_kind(def_id);
|
||||
match def_kind {
|
||||
DefKind::Enum => Self::Enum,
|
||||
DefKind::Fn => Self::Function,
|
||||
DefKind::Mod => Self::Module,
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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 })
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -835,26 +833,36 @@ fn print_higher_ranked_params_with_space(
|
|||
})
|
||||
}
|
||||
|
||||
pub(crate) fn fragment(did: DefId, tcx: TyCtxt<'_>) -> impl Display {
|
||||
fmt::from_fn(move |f| {
|
||||
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);
|
||||
write!(f, "#{}.{}", item_type.as_str(), tcx.item_name(did))
|
||||
}
|
||||
DefKind::Field => {
|
||||
let parent_def_id = tcx.parent(did);
|
||||
f.write_char('#')?;
|
||||
if tcx.def_kind(parent_def_id) == DefKind::Variant {
|
||||
write!(f, "variant.{}.field", tcx.item_name(parent_def_id).as_str())?;
|
||||
} else {
|
||||
f.write_str("structfield")?;
|
||||
};
|
||||
write!(f, ".{}", tcx.item_name(did))
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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))
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
|
||||
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()),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue