1
Fork 0

make doc_impl_item and render_default_items receive impl fmt::Write

This commit is contained in:
Yotam Ofek 2025-03-13 12:41:47 +00:00
parent 642995cf1c
commit f7640d5468

View file

@ -47,6 +47,7 @@ use std::path::PathBuf;
use std::{fs, str};
use askama::Template;
use itertools::Either;
use rustc_attr_parsing::{
ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince,
};
@ -1644,8 +1645,8 @@ fn render_impl(
// `containing_item` is used for rendering stability info. If the parent is a trait impl,
// `containing_item` will the grandparent, since trait impls can't have stability attached.
fn doc_impl_item(
boring: &mut String,
interesting: &mut String,
boring: impl fmt::Write,
interesting: impl fmt::Write,
cx: &Context<'_>,
item: &clean::Item,
parent: &clean::Item,
@ -1654,7 +1655,7 @@ fn render_impl(
is_default_item: bool,
trait_: Option<&clean::Trait>,
rendering_params: ImplRenderingParameters,
) {
) -> fmt::Result {
let item_type = item.type_();
let name = item.name.as_ref().unwrap();
@ -1729,15 +1730,16 @@ fn render_impl(
);
}
}
let w = if short_documented && trait_.is_some() { interesting } else { boring };
let mut w = if short_documented && trait_.is_some() {
Either::Left(interesting)
} else {
Either::Right(boring)
};
let toggled = !doc_buffer.is_empty();
if toggled {
let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
write_str(
w,
format_args!("<details class=\"toggle{method_toggle_class}\" open><summary>"),
);
write!(w, "<details class=\"toggle{method_toggle_class}\" open><summary>")?;
}
match &item.kind {
clean::MethodItem(..) | clean::RequiredMethodItem(_) => {
@ -1752,172 +1754,151 @@ fn render_impl(
.find(|item| item.name.map(|n| n == *name).unwrap_or(false))
})
.map(|item| format!("{}.{name}", item.type_()));
write_str(
write!(
w,
format_args!(
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
{}",
render_rightside(cx, item, render_mode)
),
);
render_rightside(cx, item, render_mode)
)?;
if trait_.is_some() {
// Anchors are only used on trait impls.
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
}
write_str(
write!(
w,
format_args!(
"<h4 class=\"code-header\">{}</h4></section>",
render_assoc_item(
item,
link.anchor(source_id.as_ref().unwrap_or(&id)),
ItemType::Impl,
cx,
render_mode,
),
"<h4 class=\"code-header\">{}</h4></section>",
render_assoc_item(
item,
link.anchor(source_id.as_ref().unwrap_or(&id)),
ItemType::Impl,
cx,
render_mode,
),
);
)?;
}
}
clean::RequiredAssocConstItem(generics, ty) => {
let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(&source_id);
write_str(
write!(
w,
format_args!(
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
{}",
render_rightside(cx, item, render_mode)
),
);
render_rightside(cx, item, render_mode)
)?;
if trait_.is_some() {
// Anchors are only used on trait impls.
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
}
write_str(
write!(
w,
format_args!(
"<h4 class=\"code-header\">{}</h4></section>",
assoc_const(
item,
generics,
ty,
AssocConstValue::None,
link.anchor(if trait_.is_some() { &source_id } else { &id }),
0,
cx,
)
"<h4 class=\"code-header\">{}</h4></section>",
assoc_const(
item,
generics,
ty,
AssocConstValue::None,
link.anchor(if trait_.is_some() { &source_id } else { &id }),
0,
cx,
),
);
)?;
}
clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => {
let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(&source_id);
write_str(
write!(
w,
format_args!(
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
{}",
render_rightside(cx, item, render_mode)
),
);
render_rightside(cx, item, render_mode),
)?;
if trait_.is_some() {
// Anchors are only used on trait impls.
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
}
write_str(
write!(
w,
format_args!(
"<h4 class=\"code-header\">{}</h4></section>",
assoc_const(
item,
&ci.generics,
&ci.type_,
match item.kind {
clean::ProvidedAssocConstItem(_) =>
AssocConstValue::TraitDefault(&ci.kind),
clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
_ => unreachable!(),
},
link.anchor(if trait_.is_some() { &source_id } else { &id }),
0,
cx,
)
"<h4 class=\"code-header\">{}</h4></section>",
assoc_const(
item,
&ci.generics,
&ci.type_,
match item.kind {
clean::ProvidedAssocConstItem(_) =>
AssocConstValue::TraitDefault(&ci.kind),
clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
_ => unreachable!(),
},
link.anchor(if trait_.is_some() { &source_id } else { &id }),
0,
cx,
),
);
)?;
}
clean::RequiredAssocTypeItem(generics, bounds) => {
let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(&source_id);
write_str(
write!(
w,
format_args!(
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
{}",
render_rightside(cx, item, render_mode)
),
);
render_rightside(cx, item, render_mode),
)?;
if trait_.is_some() {
// Anchors are only used on trait impls.
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
}
write_str(
write!(
w,
format_args!(
"<h4 class=\"code-header\">{}</h4></section>",
assoc_type(
item,
generics,
bounds,
None,
link.anchor(if trait_.is_some() { &source_id } else { &id }),
0,
cx,
)
"<h4 class=\"code-header\">{}</h4></section>",
assoc_type(
item,
generics,
bounds,
None,
link.anchor(if trait_.is_some() { &source_id } else { &id }),
0,
cx,
),
);
)?;
}
clean::AssocTypeItem(tydef, _bounds) => {
let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(&source_id);
write_str(
write!(
w,
format_args!(
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
"<section id=\"{id}\" class=\"{item_type}{in_trait_class}\">\
{}",
render_rightside(cx, item, render_mode)
),
);
render_rightside(cx, item, render_mode),
)?;
if trait_.is_some() {
// Anchors are only used on trait impls.
write_str(w, format_args!("<a href=\"#{id}\" class=\"anchor\">§</a>"));
write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
}
write_str(
write!(
w,
format_args!(
"<h4 class=\"code-header\">{}</h4></section>",
assoc_type(
item,
&tydef.generics,
&[], // intentionally leaving out bounds
Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)),
link.anchor(if trait_.is_some() { &source_id } else { &id }),
0,
cx,
)
"<h4 class=\"code-header\">{}</h4></section>",
assoc_type(
item,
&tydef.generics,
&[], // intentionally leaving out bounds
Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)),
link.anchor(if trait_.is_some() { &source_id } else { &id }),
0,
cx,
),
);
)?;
}
clean::StrippedItem(..) => return,
clean::StrippedItem(..) => return Ok(()),
_ => panic!("can't make docs for trait item with name {:?}", item.name),
}
w.push_str(&info_buffer);
w.write_str(&info_buffer)?;
if toggled {
w.push_str("</summary>");
w.push_str(&doc_buffer);
w.push_str("</details>");
write!(w, "</summary>{doc_buffer}</details>")?;
}
Ok(())
}
let mut impl_items = String::new();
@ -1960,7 +1941,7 @@ fn render_impl(
false,
trait_,
rendering_params,
);
)?;
}
_ => {}
}
@ -1978,7 +1959,7 @@ fn render_impl(
false,
trait_,
rendering_params,
);
)?;
}
for method in methods {
doc_impl_item(
@ -1992,20 +1973,20 @@ fn render_impl(
false,
trait_,
rendering_params,
);
)?;
}
}
fn render_default_items(
boring: &mut String,
interesting: &mut String,
mut boring: impl fmt::Write,
mut interesting: impl fmt::Write,
cx: &Context<'_>,
t: &clean::Trait,
i: &clean::Impl,
parent: &clean::Item,
render_mode: RenderMode,
rendering_params: ImplRenderingParameters,
) {
) -> fmt::Result {
for trait_item in &t.items {
// Skip over any default trait items that are impossible to reference
// (e.g. if it has a `Self: Sized` bound on an unsized type).
@ -2025,8 +2006,8 @@ fn render_impl(
let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods);
doc_impl_item(
boring,
interesting,
&mut boring,
&mut interesting,
cx,
trait_item,
parent,
@ -2035,8 +2016,9 @@ fn render_impl(
true,
Some(t),
rendering_params,
);
)?;
}
Ok(())
}
// If we've implemented a trait, then also emit documentation for all
@ -2056,7 +2038,7 @@ fn render_impl(
&i.impl_item,
render_mode,
rendering_params,
);
)?;
}
}
if render_mode == RenderMode::Normal {