Adapt librustdoc to 2024 edition lifetieme capture rules

Get rid of the `Captures` hack
This commit is contained in:
Yotam Ofek 2025-02-27 11:18:25 +00:00
parent 00523bf7c3
commit 6e86aa17ec
9 changed files with 270 additions and 429 deletions

View file

@ -1,8 +0,0 @@
/// "Signaling" trait used in impl trait to tag lifetimes that you may
/// need to capture but don't really need for other reasons.
/// Basically a workaround; see [this comment] for details.
///
/// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
pub trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}

View file

@ -48,7 +48,6 @@ pub use rustc_index::static_assert_size;
pub mod aligned; pub mod aligned;
pub mod base_n; pub mod base_n;
pub mod binary_search_util; pub mod binary_search_util;
pub mod captures;
pub mod fingerprint; pub mod fingerprint;
pub mod flat_map_in_place; pub mod flat_map_in_place;
pub mod flock; pub mod flock;

View file

@ -1150,7 +1150,7 @@ pub(crate) struct Attributes {
} }
impl Attributes { impl Attributes {
pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::MetaItemInner> + '_ { pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::MetaItemInner> {
hir_attr_lists(&self.other_attrs[..], name) hir_attr_lists(&self.other_attrs[..], name)
} }
@ -1864,7 +1864,7 @@ impl PrimitiveType {
.copied() .copied()
} }
pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> + '_ { pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> {
Self::simplified_types() Self::simplified_types()
.values() .values()
.flatten() .flatten()
@ -2259,7 +2259,7 @@ impl GenericArgs {
GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(), GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(),
} }
} }
pub(crate) fn constraints<'a>(&'a self) -> Box<dyn Iterator<Item = AssocItemConstraint> + 'a> { pub(crate) fn constraints(&self) -> Box<dyn Iterator<Item = AssocItemConstraint> + '_> {
match self { match self {
GenericArgs::AngleBracketed { constraints, .. } => { GenericArgs::AngleBracketed { constraints, .. } => {
Box::new(constraints.iter().cloned()) Box::new(constraints.iter().cloned())

View file

@ -330,7 +330,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
return Symbol::intern("()"); return Symbol::intern("()");
} }
PatKind::Slice(begin, mid, end) => { PatKind::Slice(begin, mid, end) => {
fn print_pat<'a>(pat: &'a Pat<'a>, wild: bool) -> impl Display + 'a { fn print_pat(pat: &Pat<'_>, wild: bool) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
if wild { if wild {
f.write_str("..")?; f.write_str("..")?;

View file

@ -15,7 +15,6 @@ use std::iter::{self, once};
use itertools::Either; use itertools::Either;
use rustc_abi::ExternAbi; use rustc_abi::ExternAbi;
use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince}; use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
@ -41,10 +40,10 @@ pub(crate) fn write_str(s: &mut String, f: fmt::Arguments<'_>) {
s.write_fmt(f).unwrap(); s.write_fmt(f).unwrap();
} }
pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>( pub(crate) fn print_generic_bounds(
bounds: &'a [clean::GenericBound], bounds: &[clean::GenericBound],
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> impl Display + 'a + Captures<'tcx> { ) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
let mut bounds_dup = FxHashSet::default(); let mut bounds_dup = FxHashSet::default();
@ -57,10 +56,7 @@ pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
} }
impl clean::GenericParamDef { impl clean::GenericParamDef {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| match &self.kind { fmt::from_fn(move |f| match &self.kind {
clean::GenericParamDefKind::Lifetime { outlives } => { clean::GenericParamDefKind::Lifetime { outlives } => {
write!(f, "{}", self.name)?; write!(f, "{}", self.name)?;
@ -107,10 +103,7 @@ impl clean::GenericParamDef {
} }
impl clean::Generics { impl clean::Generics {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable(); let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
if real_params.peek().is_none() { if real_params.peek().is_none() {
@ -134,10 +127,7 @@ pub(crate) enum Ending {
NoNewline, NoNewline,
} }
fn print_where_predicate<'a, 'tcx: 'a>( fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> impl Display {
predicate: &'a clean::WherePredicate,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
match predicate { match predicate {
clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
@ -173,12 +163,12 @@ fn print_where_predicate<'a, 'tcx: 'a>(
/// * The Generics from which to emit a where-clause. /// * The Generics from which to emit a where-clause.
/// * The number of spaces to indent each line with. /// * The number of spaces to indent each line with.
/// * Whether the where-clause needs to add a comma and newline after the last bound. /// * Whether the where-clause needs to add a comma and newline after the last bound.
pub(crate) fn print_where_clause<'a, 'tcx: 'a>( pub(crate) fn print_where_clause(
gens: &'a clean::Generics, gens: &clean::Generics,
cx: &'a Context<'tcx>, cx: &Context<'_>,
indent: usize, indent: usize,
ending: Ending, ending: Ending,
) -> Option<impl Display + 'a + Captures<'tcx>> { ) -> Option<impl Display> {
if gens.where_predicates.is_empty() { if gens.where_predicates.is_empty() {
return None; return None;
} }
@ -250,13 +240,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
} }
impl clean::Lifetime { impl clean::Lifetime {
pub(crate) fn print(&self) -> impl Display + '_ { pub(crate) fn print(&self) -> impl Display {
self.0.as_str() self.0.as_str()
} }
} }
impl clean::ConstantKind { impl clean::ConstantKind {
pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ { pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display {
let expr = self.expr(tcx); let expr = self.expr(tcx);
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) } if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) }
@ -265,7 +255,7 @@ impl clean::ConstantKind {
} }
impl clean::PolyTrait { impl clean::PolyTrait {
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?; print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?;
self.trait_.print(cx).fmt(f) self.trait_.print(cx).fmt(f)
@ -274,10 +264,7 @@ impl clean::PolyTrait {
} }
impl clean::GenericBound { impl clean::GenericBound {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| match self { fmt::from_fn(move |f| match self {
clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()), clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()),
clean::GenericBound::TraitBound(ty, modifiers) => { clean::GenericBound::TraitBound(ty, modifiers) => {
@ -304,7 +291,7 @@ impl clean::GenericBound {
} }
impl clean::GenericArgs { impl clean::GenericArgs {
fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> { fn print(&self, cx: &Context<'_>) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
match self { match self {
clean::GenericArgs::AngleBracketed { args, constraints } => { clean::GenericArgs::AngleBracketed { args, constraints } => {
@ -809,11 +796,11 @@ fn primitive_link_fragment(
Ok(()) Ok(())
} }
fn tybounds<'a, 'tcx: 'a>( fn tybounds(
bounds: &'a [clean::PolyTrait], bounds: &[clean::PolyTrait],
lt: &'a Option<clean::Lifetime>, lt: &Option<clean::Lifetime>,
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> impl Display + 'a + Captures<'tcx> { ) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
bounds.iter().map(|bound| bound.print(cx)).joined(" + ", f)?; bounds.iter().map(|bound| bound.print(cx)).joined(" + ", f)?;
if let Some(lt) = lt { if let Some(lt) = lt {
@ -825,11 +812,11 @@ fn tybounds<'a, 'tcx: 'a>(
}) })
} }
fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>( fn print_higher_ranked_params_with_space(
params: &'a [clean::GenericParamDef], params: &[clean::GenericParamDef],
cx: &'a Context<'tcx>, cx: &Context<'_>,
keyword: &'static str, keyword: &'static str,
) -> impl Display + 'a + Captures<'tcx> { ) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
if !params.is_empty() { if !params.is_empty() {
f.write_str(keyword)?; f.write_str(keyword)?;
@ -841,11 +828,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
}) })
} }
pub(crate) fn anchor<'a: 'cx, 'cx>( pub(crate) fn anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display {
did: DefId,
text: Symbol,
cx: &'cx Context<'a>,
) -> impl Display + Captures<'a> + 'cx {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
let parts = href(did, cx); let parts = href(did, cx);
if let Ok((url, short_ty, fqp)) = parts { if let Ok((url, short_ty, fqp)) = parts {
@ -1121,29 +1104,19 @@ fn fmt_type(
} }
impl clean::Type { impl clean::Type {
pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'b + Captures<'tcx> {
fmt::from_fn(move |f| fmt_type(self, f, false, cx)) fmt::from_fn(move |f| fmt_type(self, f, false, cx))
} }
} }
impl clean::Path { impl clean::Path {
pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'b + Captures<'tcx> {
fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx)) fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
} }
} }
impl clean::Impl { impl clean::Impl {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, use_absolute: bool, cx: &Context<'_>) -> impl Display {
&'a self,
use_absolute: bool,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
f.write_str("impl")?; f.write_str("impl")?;
self.generics.print(cx).fmt(f)?; self.generics.print(cx).fmt(f)?;
@ -1182,12 +1155,12 @@ impl clean::Impl {
print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f) print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f)
}) })
} }
fn print_type<'a, 'tcx: 'a>( fn print_type(
&self, &self,
type_: &clean::Type, type_: &clean::Type,
f: &mut fmt::Formatter<'_>, f: &mut fmt::Formatter<'_>,
use_absolute: bool, use_absolute: bool,
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> Result<(), fmt::Error> { ) -> Result<(), fmt::Error> {
if let clean::Type::Tuple(types) = type_ if let clean::Type::Tuple(types) = type_
&& let [clean::Type::Generic(name)] = &types[..] && let [clean::Type::Generic(name)] = &types[..]
@ -1258,10 +1231,7 @@ impl clean::Impl {
} }
impl clean::Arguments { impl clean::Arguments {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
self.values self.values
.iter() .iter()
@ -1301,10 +1271,7 @@ impl Display for Indent {
} }
impl clean::FnDecl { impl clean::FnDecl {
pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'b + Captures<'tcx> {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
let ellipsis = if self.c_variadic { ", ..." } else { "" }; let ellipsis = if self.c_variadic { ", ..." } else { "" };
if f.alternate() { if f.alternate() {
@ -1333,12 +1300,12 @@ impl clean::FnDecl {
/// are preserved. /// are preserved.
/// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
/// necessary. /// necessary.
pub(crate) fn full_print<'a, 'tcx: 'a>( pub(crate) fn full_print(
&'a self, &self,
header_len: usize, header_len: usize,
indent: usize, indent: usize,
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> impl Display + 'a + Captures<'tcx> { ) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
// First, generate the text form of the declaration, with no line wrapping, and count the bytes. // First, generate the text form of the declaration, with no line wrapping, and count the bytes.
let mut counter = WriteCounter(0); let mut counter = WriteCounter(0);
@ -1420,10 +1387,7 @@ impl clean::FnDecl {
self.print_output(cx).fmt(f) self.print_output(cx).fmt(f)
} }
fn print_output<'a, 'tcx: 'a>( fn print_output(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| match &self.output { fmt::from_fn(move |f| match &self.output {
clean::Tuple(tys) if tys.is_empty() => Ok(()), clean::Tuple(tys) if tys.is_empty() => Ok(()),
ty if f.alternate() => { ty if f.alternate() => {
@ -1434,10 +1398,7 @@ impl clean::FnDecl {
} }
} }
pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>( pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>) -> impl Display {
item: &clean::Item,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
use std::fmt::Write as _; use std::fmt::Write as _;
let vis: Cow<'static, str> = match item.visibility(cx.tcx()) { let vis: Cow<'static, str> = match item.visibility(cx.tcx()) {
None => "".into(), None => "".into(),
@ -1546,10 +1507,7 @@ pub(crate) fn print_constness_with_space(
} }
impl clean::Import { impl clean::Import {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| match self.kind { fmt::from_fn(move |f| match self.kind {
clean::ImportKind::Simple(name) => { clean::ImportKind::Simple(name) => {
if name == self.source.path.last() { if name == self.source.path.last() {
@ -1570,10 +1528,7 @@ impl clean::Import {
} }
impl clean::ImportSource { impl clean::ImportSource {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| match self.did { fmt::from_fn(move |f| match self.did {
Some(did) => resolved_path(f, did, &self.path, true, false, cx), Some(did) => resolved_path(f, did, &self.path, true, false, cx),
_ => { _ => {
@ -1593,10 +1548,7 @@ impl clean::ImportSource {
} }
impl clean::AssocItemConstraint { impl clean::AssocItemConstraint {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
f.write_str(self.assoc.name.as_str())?; f.write_str(self.assoc.name.as_str())?;
self.assoc.args.print(cx).fmt(f)?; self.assoc.args.print(cx).fmt(f)?;
@ -1627,15 +1579,12 @@ pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
}) })
} }
pub(crate) fn print_default_space<'a>(v: bool) -> &'a str { pub(crate) fn print_default_space(v: bool) -> &'static str {
if v { "default " } else { "" } if v { "default " } else { "" }
} }
impl clean::GenericArg { impl clean::GenericArg {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| match self { fmt::from_fn(move |f| match self {
clean::GenericArg::Lifetime(lt) => lt.print().fmt(f), clean::GenericArg::Lifetime(lt) => lt.print().fmt(f),
clean::GenericArg::Type(ty) => ty.print(cx).fmt(f), clean::GenericArg::Type(ty) => ty.print(cx).fmt(f),
@ -1646,10 +1595,7 @@ impl clean::GenericArg {
} }
impl clean::Term { impl clean::Term {
pub(crate) fn print<'a, 'tcx: 'a>( pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
&'a self,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
fmt::from_fn(move |f| match self { fmt::from_fn(move |f| match self {
clean::Term::Type(ty) => ty.print(cx).fmt(f), clean::Term::Type(ty) => ty.print(cx).fmt(f),
clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f), clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f),

View file

@ -47,7 +47,6 @@ use rinja::Template;
use rustc_attr_parsing::{ use rustc_attr_parsing::{
ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince, ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince,
}; };
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir::Mutability; use rustc_hir::Mutability;
use rustc_hir::def_id::{DefId, DefIdSet}; use rustc_hir::def_id::{DefId, DefIdSet};
@ -82,7 +81,7 @@ use crate::html::{highlight, sources};
use crate::scrape_examples::{CallData, CallLocation}; use crate::scrape_examples::{CallData, CallLocation};
use crate::{DOC_RUST_LANG_ORG_VERSION, try_none}; use crate::{DOC_RUST_LANG_ORG_VERSION, try_none};
pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ { pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) } if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) }
}) })
@ -310,7 +309,7 @@ impl ItemEntry {
} }
impl ItemEntry { impl ItemEntry {
pub(crate) fn print(&self) -> impl fmt::Display + '_ { pub(crate) fn print(&self) -> impl fmt::Display {
fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name))) fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name)))
} }
} }
@ -505,12 +504,12 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
) )
} }
fn document<'a, 'cx: 'a>( fn document(
cx: &'a Context<'cx>, cx: &Context<'_>,
item: &'a clean::Item, item: &clean::Item,
parent: Option<&'a clean::Item>, parent: Option<&clean::Item>,
heading_offset: HeadingOffset, heading_offset: HeadingOffset,
) -> impl fmt::Display + 'a + Captures<'cx> { ) -> impl fmt::Display {
if let Some(ref name) = item.name { if let Some(ref name) = item.name {
info!("Documenting {name}"); info!("Documenting {name}");
} }
@ -526,12 +525,12 @@ fn document<'a, 'cx: 'a>(
} }
/// Render md_text as markdown. /// Render md_text as markdown.
fn render_markdown<'a, 'cx: 'a>( fn render_markdown(
cx: &'a Context<'cx>, cx: &Context<'_>,
md_text: &'a str, md_text: &str,
links: Vec<RenderedLink>, links: Vec<RenderedLink>,
heading_offset: HeadingOffset, heading_offset: HeadingOffset,
) -> impl fmt::Display + 'a + Captures<'cx> { ) -> impl fmt::Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
write!( write!(
f, f,
@ -552,13 +551,13 @@ fn render_markdown<'a, 'cx: 'a>(
/// Writes a documentation block containing only the first paragraph of the documentation. If the /// Writes a documentation block containing only the first paragraph of the documentation. If the
/// docs are longer, a "Read more" link is appended to the end. /// docs are longer, a "Read more" link is appended to the end.
fn document_short<'a, 'cx: 'a>( fn document_short(
item: &'a clean::Item, item: &clean::Item,
cx: &'a Context<'cx>, cx: &Context<'_>,
link: AssocItemLink<'a>, link: AssocItemLink<'_>,
parent: &'a clean::Item, parent: &clean::Item,
show_def_docs: bool, show_def_docs: bool,
) -> impl fmt::Display + 'a + Captures<'cx> { ) -> impl fmt::Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
document_item_info(cx, item, Some(parent)).render_into(f).unwrap(); document_item_info(cx, item, Some(parent)).render_into(f).unwrap();
if !show_def_docs { if !show_def_docs {
@ -595,28 +594,28 @@ fn document_short<'a, 'cx: 'a>(
}) })
} }
fn document_full_collapsible<'a, 'cx: 'a>( fn document_full_collapsible(
item: &'a clean::Item, item: &clean::Item,
cx: &'a Context<'cx>, cx: &Context<'_>,
heading_offset: HeadingOffset, heading_offset: HeadingOffset,
) -> impl fmt::Display + 'a + Captures<'cx> { ) -> impl fmt::Display {
document_full_inner(item, cx, true, heading_offset) document_full_inner(item, cx, true, heading_offset)
} }
fn document_full<'a, 'cx: 'a>( fn document_full(
item: &'a clean::Item, item: &clean::Item,
cx: &'a Context<'cx>, cx: &Context<'_>,
heading_offset: HeadingOffset, heading_offset: HeadingOffset,
) -> impl fmt::Display + 'a + Captures<'cx> { ) -> impl fmt::Display {
document_full_inner(item, cx, false, heading_offset) document_full_inner(item, cx, false, heading_offset)
} }
fn document_full_inner<'a, 'cx: 'a>( fn document_full_inner(
item: &'a clean::Item, item: &clean::Item,
cx: &'a Context<'cx>, cx: &Context<'_>,
is_collapsible: bool, is_collapsible: bool,
heading_offset: HeadingOffset, heading_offset: HeadingOffset,
) -> impl fmt::Display + 'a + Captures<'cx> { ) -> impl fmt::Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
if let Some(s) = item.opt_doc_value() { if let Some(s) = item.opt_doc_value() {
debug!("Doc block: =====\n{s}\n====="); debug!("Doc block: =====\n{s}\n=====");
@ -797,11 +796,11 @@ pub(crate) fn render_impls(
} }
/// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item.
fn assoc_href_attr<'a, 'tcx>( fn assoc_href_attr(
it: &clean::Item, it: &clean::Item,
link: AssocItemLink<'a>, link: AssocItemLink<'_>,
cx: &Context<'tcx>, cx: &Context<'_>,
) -> Option<impl fmt::Display + 'a + Captures<'tcx>> { ) -> Option<impl fmt::Display> {
let name = it.name.unwrap(); let name = it.name.unwrap();
let item_type = it.type_(); let item_type = it.type_();
@ -877,15 +876,15 @@ enum AssocConstValue<'a> {
None, None,
} }
fn assoc_const<'a, 'tcx>( fn assoc_const(
it: &'a clean::Item, it: &clean::Item,
generics: &'a clean::Generics, generics: &clean::Generics,
ty: &'a clean::Type, ty: &clean::Type,
value: AssocConstValue<'a>, value: AssocConstValue<'_>,
link: AssocItemLink<'a>, link: AssocItemLink<'_>,
indent: usize, indent: usize,
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
let tcx = cx.tcx(); let tcx = cx.tcx();
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
write!( write!(
@ -917,15 +916,15 @@ fn assoc_const<'a, 'tcx>(
}) })
} }
fn assoc_type<'a, 'tcx>( fn assoc_type(
it: &'a clean::Item, it: &clean::Item,
generics: &'a clean::Generics, generics: &clean::Generics,
bounds: &'a [clean::GenericBound], bounds: &[clean::GenericBound],
default: Option<&'a clean::Type>, default: Option<&clean::Type>,
link: AssocItemLink<'a>, link: AssocItemLink<'_>,
indent: usize, indent: usize,
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
write!( write!(
w, w,
@ -947,15 +946,15 @@ fn assoc_type<'a, 'tcx>(
}) })
} }
fn assoc_method<'a, 'tcx>( fn assoc_method(
meth: &'a clean::Item, meth: &clean::Item,
g: &'a clean::Generics, g: &clean::Generics,
d: &'a clean::FnDecl, d: &clean::FnDecl,
link: AssocItemLink<'a>, link: AssocItemLink<'_>,
parent: ItemType, parent: ItemType,
cx: &'a Context<'tcx>, cx: &Context<'_>,
render_mode: RenderMode, render_mode: RenderMode,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
let tcx = cx.tcx(); let tcx = cx.tcx();
let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item"); let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item");
let name = meth.name.as_ref().unwrap(); let name = meth.name.as_ref().unwrap();
@ -1031,7 +1030,7 @@ fn render_stability_since_raw_with_extra(
stable_version: Option<StableSince>, stable_version: Option<StableSince>,
const_stability: Option<ConstStability>, const_stability: Option<ConstStability>,
extra_class: &str, extra_class: &str,
) -> Option<impl fmt::Display + '_> { ) -> Option<impl fmt::Display> {
let mut title = String::new(); let mut title = String::new();
let mut stability = String::new(); let mut stability = String::new();
@ -1102,13 +1101,13 @@ fn render_stability_since_raw(
render_stability_since_raw_with_extra(ver, const_stability, "") render_stability_since_raw_with_extra(ver, const_stability, "")
} }
fn render_assoc_item<'a, 'tcx>( fn render_assoc_item(
item: &'a clean::Item, item: &clean::Item,
link: AssocItemLink<'a>, link: AssocItemLink<'_>,
parent: ItemType, parent: ItemType,
cx: &'a Context<'tcx>, cx: &Context<'_>,
render_mode: RenderMode, render_mode: RenderMode,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |f| match &item.kind { fmt::from_fn(move |f| match &item.kind {
clean::StrippedItem(..) => Ok(()), clean::StrippedItem(..) => Ok(()),
clean::RequiredMethodItem(m) | clean::MethodItem(m, _) => { clean::RequiredMethodItem(m) | clean::MethodItem(m, _) => {
@ -1170,11 +1169,7 @@ fn render_assoc_item<'a, 'tcx>(
// When an attribute is rendered inside a `<pre>` tag, it is formatted using // When an attribute is rendered inside a `<pre>` tag, it is formatted using
// a whitespace prefix and newline. // a whitespace prefix and newline.
fn render_attributes_in_pre<'a, 'tcx: 'a>( fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display {
it: &'a clean::Item,
prefix: &'a str,
cx: &'a Context<'tcx>,
) -> impl fmt::Display + Captures<'a> + Captures<'tcx> {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
for a in it.attributes(cx.tcx(), cx.cache(), false) { for a in it.attributes(cx.tcx(), cx.cache(), false) {
writeln!(f, "{prefix}{a}")?; writeln!(f, "{prefix}{a}")?;
@ -1206,12 +1201,12 @@ impl<'a> AssocItemLink<'a> {
} }
} }
pub fn write_section_heading<'a>( pub fn write_section_heading(
title: &'a str, title: &str,
id: &'a str, id: &str,
extra_class: Option<&'a str>, extra_class: Option<&str>,
extra: impl fmt::Display + 'a, extra: impl fmt::Display,
) -> impl fmt::Display + 'a { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
let (extra_class, whitespace) = match extra_class { let (extra_class, whitespace) = match extra_class {
Some(extra) => (extra, " "), Some(extra) => (extra, " "),
@ -1227,7 +1222,7 @@ pub fn write_section_heading<'a>(
}) })
} }
fn write_impl_section_heading<'a>(title: &'a str, id: &'a str) -> impl fmt::Display + 'a { fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
write_section_heading(title, id, None, "") write_section_heading(title, id, None, "")
} }
@ -1276,12 +1271,12 @@ pub(crate) fn render_all_impls(
} }
} }
fn render_assoc_items<'a, 'cx: 'a>( fn render_assoc_items(
cx: &'a Context<'cx>, cx: &Context<'_>,
containing_item: &'a clean::Item, containing_item: &clean::Item,
it: DefId, it: DefId,
what: AssocItemRender<'a>, what: AssocItemRender<'_>,
) -> impl fmt::Display + 'a + Captures<'cx> { ) -> impl fmt::Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
let mut derefs = DefIdSet::default(); let mut derefs = DefIdSet::default();
derefs.insert(it); derefs.insert(it);
@ -1466,10 +1461,10 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
} }
} }
pub(crate) fn notable_traits_button<'a, 'tcx>( pub(crate) fn notable_traits_button(
ty: &'a clean::Type, ty: &clean::Type,
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> Option<impl fmt::Display + 'a + Captures<'tcx>> { ) -> Option<impl fmt::Display> {
let mut has_notable_trait = false; let mut has_notable_trait = false;
if ty.is_unit() { if ty.is_unit() {
@ -1623,16 +1618,16 @@ struct ImplRenderingParameters {
toggle_open_by_default: bool, toggle_open_by_default: bool,
} }
fn render_impl<'a, 'tcx>( fn render_impl(
cx: &'a Context<'tcx>, cx: &Context<'_>,
i: &'a Impl, i: &Impl,
parent: &'a clean::Item, parent: &clean::Item,
link: AssocItemLink<'a>, link: AssocItemLink<'_>,
render_mode: RenderMode, render_mode: RenderMode,
use_absolute: Option<bool>, use_absolute: Option<bool>,
aliases: &'a [String], aliases: &[String],
rendering_params: ImplRenderingParameters, rendering_params: ImplRenderingParameters,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
let cache = &cx.shared.cache; let cache = &cx.shared.cache;
let traits = &cache.traits; let traits = &cache.traits;
@ -1780,7 +1775,7 @@ fn render_impl<'a, 'tcx>(
); );
} }
} }
clean::RequiredAssocConstItem(ref generics, ref ty) => { clean::RequiredAssocConstItem(generics, ty) => {
let source_id = format!("{item_type}.{name}"); let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(&source_id); let id = cx.derive_id(&source_id);
write_str( write_str(
@ -1847,7 +1842,7 @@ fn render_impl<'a, 'tcx>(
), ),
); );
} }
clean::RequiredAssocTypeItem(ref generics, ref bounds) => { clean::RequiredAssocTypeItem(generics, bounds) => {
let source_id = format!("{item_type}.{name}"); let source_id = format!("{item_type}.{name}");
let id = cx.derive_id(&source_id); let id = cx.derive_id(&source_id);
write_str( write_str(
@ -2135,11 +2130,11 @@ fn render_impl<'a, 'tcx>(
// Render the items that appear on the right side of methods, impls, and // Render the items that appear on the right side of methods, impls, and
// associated types. For example "1.0.0 (const: 1.39.0) · source". // associated types. For example "1.0.0 (const: 1.39.0) · source".
fn render_rightside<'a, 'tcx>( fn render_rightside(
cx: &'a Context<'tcx>, cx: &Context<'_>,
item: &'a clean::Item, item: &clean::Item,
render_mode: RenderMode, render_mode: RenderMode,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
let tcx = cx.tcx(); let tcx = cx.tcx();
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
@ -2174,17 +2169,17 @@ fn render_rightside<'a, 'tcx>(
}) })
} }
pub(crate) fn render_impl_summary<'a, 'tcx>( pub(crate) fn render_impl_summary(
cx: &'a Context<'tcx>, cx: &Context<'_>,
i: &'a Impl, i: &Impl,
parent: &'a clean::Item, parent: &clean::Item,
show_def_docs: bool, show_def_docs: bool,
use_absolute: Option<bool>, use_absolute: Option<bool>,
// This argument is used to reference same type with different paths to avoid duplication // This argument is used to reference same type with different paths to avoid duplication
// in documentation pages for trait with automatic implementations like "Send" and "Sync". // in documentation pages for trait with automatic implementations like "Send" and "Sync".
aliases: &'a [String], aliases: &[String],
doc: Option<&'a str>, doc: Option<&str>,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
let inner_impl = i.inner_impl(); let inner_impl = i.inner_impl();
let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id)); let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id));

View file

@ -4,7 +4,6 @@ use std::fmt::{Display, Write as _};
use rinja::Template; use rinja::Template;
use rustc_abi::VariantIdx; use rustc_abi::VariantIdx;
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::CtorKind; use rustc_hir::def::CtorKind;
@ -92,44 +91,32 @@ macro_rules! item_template {
macro_rules! item_template_methods { macro_rules! item_template_methods {
() => {}; () => {};
(document $($rest:tt)*) => { (document $($rest:tt)*) => {
fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { fn document(&self) -> impl fmt::Display {
fmt::from_fn(move |f| { let (item, cx) = self.item_and_cx();
let (item, cx) = self.item_and_cx(); document(cx, item, None, HeadingOffset::H2)
let v = document(cx, item, None, HeadingOffset::H2);
write!(f, "{v}")
})
} }
item_template_methods!($($rest)*); item_template_methods!($($rest)*);
}; };
(document_type_layout $($rest:tt)*) => { (document_type_layout $($rest:tt)*) => {
fn document_type_layout<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { fn document_type_layout(&self) -> impl fmt::Display {
fmt::from_fn(move |f| { let (item, cx) = self.item_and_cx();
let (item, cx) = self.item_and_cx(); let def_id = item.item_id.expect_def_id();
let def_id = item.item_id.expect_def_id(); document_type_layout(cx, def_id)
let v = document_type_layout(cx, def_id);
write!(f, "{v}")
})
} }
item_template_methods!($($rest)*); item_template_methods!($($rest)*);
}; };
(render_attributes_in_pre $($rest:tt)*) => { (render_attributes_in_pre $($rest:tt)*) => {
fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { fn render_attributes_in_pre(&self) -> impl fmt::Display {
fmt::from_fn(move |f| { let (item, cx) = self.item_and_cx();
let (item, cx) = self.item_and_cx(); render_attributes_in_pre(item, "", cx)
let v = render_attributes_in_pre(item, "", cx);
write!(f, "{v}")
})
} }
item_template_methods!($($rest)*); item_template_methods!($($rest)*);
}; };
(render_assoc_items $($rest:tt)*) => { (render_assoc_items $($rest:tt)*) => {
fn render_assoc_items<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { fn render_assoc_items(&self) -> impl fmt::Display {
fmt::from_fn(move |f| { let (item, cx) = self.item_and_cx();
let (item, cx) = self.item_and_cx(); let def_id = item.item_id.expect_def_id();
let def_id = item.item_id.expect_def_id(); render_assoc_items(cx, item, def_id, AssocItemRender::All)
let v = render_assoc_items(cx, item, def_id, AssocItemRender::All);
write!(f, "{v}")
})
} }
item_template_methods!($($rest)*); item_template_methods!($($rest)*);
}; };
@ -162,10 +149,7 @@ struct ItemVars<'a> {
src_href: Option<&'a str>, src_href: Option<&'a str>,
} }
pub(super) fn print_item<'a, 'tcx>( pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Display {
cx: &'a Context<'tcx>,
item: &'a clean::Item,
) -> impl fmt::Display + 'a + Captures<'tcx> {
debug_assert!(!item.is_stripped()); debug_assert!(!item.is_stripped());
fmt::from_fn(|buf| { fmt::from_fn(|buf| {
@ -241,30 +225,30 @@ pub(super) fn print_item<'a, 'tcx>(
item_vars.render_into(buf).unwrap(); item_vars.render_into(buf).unwrap();
match &item.kind { match &item.kind {
clean::ModuleItem(ref m) => { clean::ModuleItem(m) => {
write!(buf, "{}", item_module(cx, item, &m.items)) write!(buf, "{}", item_module(cx, item, &m.items))
} }
clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => { clean::FunctionItem(f) | clean::ForeignFunctionItem(f, _) => {
write!(buf, "{}", item_function(cx, item, f)) write!(buf, "{}", item_function(cx, item, f))
} }
clean::TraitItem(ref t) => write!(buf, "{}", item_trait(cx, item, t)), clean::TraitItem(t) => write!(buf, "{}", item_trait(cx, item, t)),
clean::StructItem(ref s) => { clean::StructItem(s) => {
write!(buf, "{}", item_struct(cx, item, s)) write!(buf, "{}", item_struct(cx, item, s))
} }
clean::UnionItem(ref s) => write!(buf, "{}", item_union(cx, item, s)), clean::UnionItem(s) => write!(buf, "{}", item_union(cx, item, s)),
clean::EnumItem(ref e) => write!(buf, "{}", item_enum(cx, item, e)), clean::EnumItem(e) => write!(buf, "{}", item_enum(cx, item, e)),
clean::TypeAliasItem(ref t) => { clean::TypeAliasItem(t) => {
write!(buf, "{}", item_type_alias(cx, item, t)) write!(buf, "{}", item_type_alias(cx, item, t))
} }
clean::MacroItem(ref m) => write!(buf, "{}", item_macro(cx, item, m)), clean::MacroItem(m) => write!(buf, "{}", item_macro(cx, item, m)),
clean::ProcMacroItem(ref m) => { clean::ProcMacroItem(m) => {
write!(buf, "{}", item_proc_macro(cx, item, m)) write!(buf, "{}", item_proc_macro(cx, item, m))
} }
clean::PrimitiveItem(_) => write!(buf, "{}", item_primitive(cx, item)), clean::PrimitiveItem(_) => write!(buf, "{}", item_primitive(cx, item)),
clean::StaticItem(ref i) => { clean::StaticItem(i) => {
write!(buf, "{}", item_static(cx, item, i, None)) write!(buf, "{}", item_static(cx, item, i, None))
} }
clean::ForeignStaticItem(ref i, safety) => { clean::ForeignStaticItem(i, safety) => {
write!(buf, "{}", item_static(cx, item, i, Some(*safety))) write!(buf, "{}", item_static(cx, item, i, Some(*safety)))
} }
clean::ConstantItem(ci) => { clean::ConstantItem(ci) => {
@ -274,7 +258,7 @@ pub(super) fn print_item<'a, 'tcx>(
write!(buf, "{}", item_foreign_type(cx, item)) write!(buf, "{}", item_foreign_type(cx, item))
} }
clean::KeywordItem => write!(buf, "{}", item_keyword(cx, item)), clean::KeywordItem => write!(buf, "{}", item_keyword(cx, item)),
clean::TraitAliasItem(ref ta) => { clean::TraitAliasItem(ta) => {
write!(buf, "{}", item_trait_alias(cx, item, ta)) write!(buf, "{}", item_trait_alias(cx, item, ta))
} }
_ => { _ => {
@ -321,11 +305,7 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display {
fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>); fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>);
} }
fn item_module<'a, 'tcx>( fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> impl fmt::Display {
cx: &'a Context<'tcx>,
item: &'a clean::Item,
items: &'a [clean::Item],
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?; write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?;
@ -541,14 +521,14 @@ fn item_module<'a, 'tcx>(
/// Render the stability, deprecation and portability tags that are displayed in the item's summary /// Render the stability, deprecation and portability tags that are displayed in the item's summary
/// at the module level. /// at the module level.
fn extra_info_tags<'a, 'tcx: 'a>( fn extra_info_tags(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'_>,
item: &'a clean::Item, item: &clean::Item,
parent: &'a clean::Item, parent: &clean::Item,
import_def_id: Option<DefId>, import_def_id: Option<DefId>,
) -> impl Display + 'a + Captures<'tcx> { ) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
fn tag_html<'a>(class: &'a str, title: &'a str, contents: &'a str) -> impl Display + 'a { fn tag_html(class: &str, title: &str, contents: &str) -> impl Display {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
write!( write!(
f, f,
@ -597,11 +577,7 @@ fn extra_info_tags<'a, 'tcx: 'a>(
}) })
} }
fn item_function<'a, 'tcx>( fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
f: &'a clean::Function,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
let tcx = cx.tcx(); let tcx = cx.tcx();
let header = it.fn_header(tcx).expect("printing a function which isn't a function"); let header = it.fn_header(tcx).expect("printing a function which isn't a function");
@ -657,11 +633,7 @@ fn item_function<'a, 'tcx>(
}) })
} }
fn item_trait<'a, 'tcx>( fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
t: &'a clean::Trait,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
let tcx = cx.tcx(); let tcx = cx.tcx();
let bounds = bounds(&t.bounds, false, cx); let bounds = bounds(&t.bounds, false, cx);
@ -831,11 +803,7 @@ fn item_trait<'a, 'tcx>(
// Trait documentation // Trait documentation
write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
fn trait_item<'a, 'tcx>( fn trait_item(cx: &Context<'_>, m: &clean::Item, t: &clean::Item) -> impl fmt::Display {
cx: &'a Context<'tcx>,
m: &'a clean::Item,
t: &'a clean::Item,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
let name = m.name.unwrap(); let name = m.name.unwrap();
info!("Documenting {name} on {ty_name:?}", ty_name = t.name); info!("Documenting {name} on {ty_name:?}", ty_name = t.name);
@ -1021,7 +989,7 @@ fn item_trait<'a, 'tcx>(
extern_crates.insert(did.krate); extern_crates.insert(did.krate);
} }
match implementor.inner_impl().for_.without_borrowed_ref() { match implementor.inner_impl().for_.without_borrowed_ref() {
clean::Type::Path { ref path } if !path.is_assoc_ty() => { clean::Type::Path { path } if !path.is_assoc_ty() => {
let did = path.def_id(); let did = path.def_id();
let &mut (prev_did, ref mut has_duplicates) = let &mut (prev_did, ref mut has_duplicates) =
implementor_dups.entry(path.last()).or_insert((did, false)); implementor_dups.entry(path.last()).or_insert((did, false));
@ -1254,11 +1222,11 @@ fn item_trait<'a, 'tcx>(
}) })
} }
fn item_trait_alias<'a, 'tcx>( fn item_trait_alias(
cx: &'a Context<'tcx>, cx: &Context<'_>,
it: &'a clean::Item, it: &clean::Item,
t: &'a clean::TraitAlias, t: &clean::TraitAlias,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(|w| { fmt::from_fn(|w| {
wrap_item(w, |w| { wrap_item(w, |w| {
write!( write!(
@ -1285,11 +1253,7 @@ fn item_trait_alias<'a, 'tcx>(
}) })
} }
fn item_type_alias<'a, 'tcx>( fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
t: &'a clean::TypeAlias,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
wrap_item(w, |w| { wrap_item(w, |w| {
write!( write!(
@ -1499,11 +1463,7 @@ fn item_type_alias<'a, 'tcx>(
}) })
} }
fn item_union<'a, 'tcx>( fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
s: &'a clean::Union,
) -> impl fmt::Display + 'a + Captures<'tcx> {
item_template!( item_template!(
#[template(path = "item_union.html")] #[template(path = "item_union.html")]
struct ItemUnion<'a, 'cx> { struct ItemUnion<'a, 'cx> {
@ -1515,35 +1475,20 @@ fn item_union<'a, 'tcx>(
); );
impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> { impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
fn render_union<'b>(&'b self) -> impl Display + Captures<'a> + 'b + Captures<'cx> { fn render_union(&self) -> impl Display {
fmt::from_fn(move |f| { render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx)
let v = render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx);
write!(f, "{v}")
})
} }
fn document_field<'b>( fn document_field(&self, field: &'a clean::Item) -> impl Display {
&'b self, document(self.cx, field, Some(self.it), HeadingOffset::H3)
field: &'a clean::Item,
) -> impl Display + Captures<'a> + 'b + Captures<'cx> {
fmt::from_fn(move |f| {
let v = document(self.cx, field, Some(self.it), HeadingOffset::H3);
write!(f, "{v}")
})
} }
fn stability_field(&self, field: &clean::Item) -> Option<String> { fn stability_field(&self, field: &clean::Item) -> Option<String> {
field.stability_class(self.cx.tcx()) field.stability_class(self.cx.tcx())
} }
fn print_ty<'b>( fn print_ty(&self, ty: &'a clean::Type) -> impl Display {
&'b self, ty.print(self.cx)
ty: &'a clean::Type,
) -> impl Display + Captures<'a> + 'b + Captures<'cx> {
fmt::from_fn(move |f| {
let v = ty.print(self.cx);
write!(f, "{v}")
})
} }
fn fields_iter( fn fields_iter(
@ -1566,10 +1511,7 @@ fn item_union<'a, 'tcx>(
}) })
} }
fn print_tuple_struct_fields<'a, 'cx: 'a>( fn print_tuple_struct_fields(cx: &Context<'_>, s: &[clean::Item]) -> impl Display {
cx: &'a Context<'cx>,
s: &'a [clean::Item],
) -> impl Display + 'a + Captures<'cx> {
fmt::from_fn(|f| { fmt::from_fn(|f| {
if !s.is_empty() if !s.is_empty()
&& s.iter().all(|field| { && s.iter().all(|field| {
@ -1591,11 +1533,7 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>(
}) })
} }
fn item_enum<'a, 'tcx>( fn item_enum(cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
e: &'a clean::Enum,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
let count_variants = e.variants().count(); let count_variants = e.variants().count();
wrap_item(w, |w| { wrap_item(w, |w| {
@ -1658,14 +1596,14 @@ fn should_show_enum_discriminant(
repr.c() || repr.int.is_some() repr.c() || repr.int.is_some()
} }
fn display_c_like_variant<'a, 'tcx>( fn display_c_like_variant(
cx: &'a Context<'tcx>, cx: &Context<'_>,
item: &'a clean::Item, item: &clean::Item,
variant: &'a clean::Variant, variant: &clean::Variant,
index: VariantIdx, index: VariantIdx,
should_show_enum_discriminant: bool, should_show_enum_discriminant: bool,
enum_def_id: DefId, enum_def_id: DefId,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
let name = item.name.unwrap(); let name = item.name.unwrap();
if let Some(ref value) = variant.discriminant { if let Some(ref value) = variant.discriminant {
@ -1685,15 +1623,15 @@ fn display_c_like_variant<'a, 'tcx>(
}) })
} }
fn render_enum_fields<'a, 'tcx>( fn render_enum_fields(
cx: &'a Context<'tcx>, cx: &Context<'_>,
g: Option<&'a clean::Generics>, g: Option<&clean::Generics>,
variants: &'a IndexVec<VariantIdx, clean::Item>, variants: &IndexVec<VariantIdx, clean::Item>,
count_variants: usize, count_variants: usize,
has_stripped_entries: bool, has_stripped_entries: bool,
is_non_exhaustive: bool, is_non_exhaustive: bool,
enum_def_id: DefId, enum_def_id: DefId,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
let should_show_enum_discriminant = let should_show_enum_discriminant =
should_show_enum_discriminant(cx, enum_def_id, variants); should_show_enum_discriminant(cx, enum_def_id, variants);
@ -1764,12 +1702,12 @@ fn render_enum_fields<'a, 'tcx>(
}) })
} }
fn item_variants<'a, 'tcx>( fn item_variants(
cx: &'a Context<'tcx>, cx: &Context<'_>,
it: &'a clean::Item, it: &clean::Item,
variants: &'a IndexVec<VariantIdx, clean::Item>, variants: &IndexVec<VariantIdx, clean::Item>,
enum_def_id: DefId, enum_def_id: DefId,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
let tcx = cx.tcx(); let tcx = cx.tcx();
write!( write!(
@ -1895,11 +1833,7 @@ fn item_variants<'a, 'tcx>(
}) })
} }
fn item_macro<'a, 'tcx>( fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
t: &'a clean::Macro,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
wrap_item(w, |w| { wrap_item(w, |w| {
// FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`. // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`.
@ -1912,11 +1846,7 @@ fn item_macro<'a, 'tcx>(
}) })
} }
fn item_proc_macro<'a, 'tcx>( fn item_proc_macro(cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
m: &'a clean::ProcMacro,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
wrap_item(w, |w| { wrap_item(w, |w| {
let name = it.name.expect("proc-macros always have names"); let name = it.name.expect("proc-macros always have names");
@ -1947,10 +1877,7 @@ fn item_proc_macro<'a, 'tcx>(
}) })
} }
fn item_primitive<'a, 'tcx>( fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
let def_id = it.item_id.expect_def_id(); let def_id = it.item_id.expect_def_id();
write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?; write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
@ -1968,13 +1895,13 @@ fn item_primitive<'a, 'tcx>(
}) })
} }
fn item_constant<'a, 'tcx>( fn item_constant(
cx: &'a Context<'tcx>, cx: &Context<'_>,
it: &'a clean::Item, it: &clean::Item,
generics: &'a clean::Generics, generics: &clean::Generics,
ty: &'a clean::Type, ty: &clean::Type,
c: &'a clean::ConstantKind, c: &clean::ConstantKind,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(|w| { fmt::from_fn(|w| {
wrap_item(w, |w| { wrap_item(w, |w| {
let tcx = cx.tcx(); let tcx = cx.tcx();
@ -2028,11 +1955,7 @@ fn item_constant<'a, 'tcx>(
}) })
} }
fn item_struct<'a, 'tcx>( fn item_struct(cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
s: &'a clean::Struct,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
wrap_item(w, |w| { wrap_item(w, |w| {
render_attributes_in_code(w, it, cx); render_attributes_in_code(w, it, cx);
@ -2056,12 +1979,12 @@ fn item_struct<'a, 'tcx>(
}) })
} }
fn item_fields<'a, 'tcx>( fn item_fields(
cx: &'a Context<'tcx>, cx: &Context<'_>,
it: &'a clean::Item, it: &clean::Item,
fields: &'a [clean::Item], fields: &[clean::Item],
ctor_kind: Option<CtorKind>, ctor_kind: Option<CtorKind>,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
let mut fields = fields let mut fields = fields
.iter() .iter()
@ -2111,12 +2034,12 @@ fn item_fields<'a, 'tcx>(
}) })
} }
fn item_static<'a, 'tcx>( fn item_static(
cx: &'a Context<'tcx>, cx: &Context<'_>,
it: &'a clean::Item, it: &clean::Item,
s: &'a clean::Static, s: &clean::Static,
safety: Option<hir::Safety>, safety: Option<hir::Safety>,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
wrap_item(w, |w| { wrap_item(w, |w| {
render_attributes_in_code(w, it, cx); render_attributes_in_code(w, it, cx);
@ -2135,10 +2058,7 @@ fn item_static<'a, 'tcx>(
}) })
} }
fn item_foreign_type<'a, 'tcx>( fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
) -> impl fmt::Display + 'a + Captures<'tcx> {
fmt::from_fn(|w| { fmt::from_fn(|w| {
wrap_item(w, |w| { wrap_item(w, |w| {
w.write_str("extern {\n")?; w.write_str("extern {\n")?;
@ -2155,10 +2075,7 @@ fn item_foreign_type<'a, 'tcx>(
}) })
} }
fn item_keyword<'a, 'tcx>( fn item_keyword(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
cx: &'a Context<'tcx>,
it: &'a clean::Item,
) -> impl fmt::Display + 'a + Captures<'tcx> {
document(cx, it, None, HeadingOffset::H2) document(cx, it, None, HeadingOffset::H2)
} }
@ -2268,18 +2185,14 @@ pub(super) fn full_path(cx: &Context<'_>, item: &clean::Item) -> String {
s s
} }
pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display + '_ { pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display {
fmt::from_fn(move |f| match ty { fmt::from_fn(move |f| match ty {
ItemType::Module => write!(f, "{}index.html", ensure_trailing_slash(name)), ItemType::Module => write!(f, "{}index.html", ensure_trailing_slash(name)),
_ => write!(f, "{ty}.{name}.html"), _ => write!(f, "{ty}.{name}.html"),
}) })
} }
fn bounds<'a, 'tcx>( fn bounds(bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) -> impl Display {
bounds: &'a [clean::GenericBound],
trait_alias: bool,
cx: &'a Context<'tcx>,
) -> impl Display + 'a + Captures<'tcx> {
(!bounds.is_empty()) (!bounds.is_empty())
.then_some(fmt::from_fn(move |f| { .then_some(fmt::from_fn(move |f| {
let has_lots_of_bounds = bounds.len() > 2; let has_lots_of_bounds = bounds.len() > 2;
@ -2329,13 +2242,13 @@ impl Ord for ImplString {
} }
} }
fn render_implementor<'a, 'tcx>( fn render_implementor(
cx: &'a Context<'tcx>, cx: &Context<'_>,
implementor: &'a Impl, implementor: &Impl,
trait_: &'a clean::Item, trait_: &clean::Item,
implementor_dups: &'a FxHashMap<Symbol, (DefId, bool)>, implementor_dups: &FxHashMap<Symbol, (DefId, bool)>,
aliases: &'a [String], aliases: &[String],
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
// If there's already another implementor that has the same abridged name, use the // If there's already another implementor that has the same abridged name, use the
// full path, for example in `std::iter::ExactSizeIterator` // full path, for example in `std::iter::ExactSizeIterator`
let use_absolute = match implementor.inner_impl().for_ { let use_absolute = match implementor.inner_impl().for_ {
@ -2364,12 +2277,12 @@ fn render_implementor<'a, 'tcx>(
) )
} }
fn render_union<'a, 'cx: 'a>( fn render_union(
it: &'a clean::Item, it: &clean::Item,
g: Option<&'a clean::Generics>, g: Option<&clean::Generics>,
fields: &'a [clean::Item], fields: &[clean::Item],
cx: &'a Context<'cx>, cx: &Context<'_>,
) -> impl Display + 'a + Captures<'cx> { ) -> impl Display {
fmt::from_fn(move |mut f| { fmt::from_fn(move |mut f| {
write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?; write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?;
@ -2421,15 +2334,15 @@ fn render_union<'a, 'cx: 'a>(
}) })
} }
fn render_struct<'a, 'tcx>( fn render_struct(
it: &'a clean::Item, it: &clean::Item,
g: Option<&'a clean::Generics>, g: Option<&clean::Generics>,
ty: Option<CtorKind>, ty: Option<CtorKind>,
fields: &'a [clean::Item], fields: &[clean::Item],
tab: &'a str, tab: &str,
structhead: bool, structhead: bool,
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
write!( write!(
w, w,
@ -2457,15 +2370,15 @@ fn render_struct<'a, 'tcx>(
}) })
} }
fn render_struct_fields<'a, 'tcx>( fn render_struct_fields(
g: Option<&'a clean::Generics>, g: Option<&clean::Generics>,
ty: Option<CtorKind>, ty: Option<CtorKind>,
fields: &'a [clean::Item], fields: &[clean::Item],
tab: &'a str, tab: &str,
structhead: bool, structhead: bool,
has_stripped_entries: bool, has_stripped_entries: bool,
cx: &'a Context<'tcx>, cx: &Context<'_>,
) -> impl fmt::Display + 'a + Captures<'tcx> { ) -> impl fmt::Display {
fmt::from_fn(move |w| { fmt::from_fn(move |w| {
match ty { match ty {
None => { None => {
@ -2581,7 +2494,7 @@ fn document_non_exhaustive_header(item: &clean::Item) -> &str {
if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" } if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" }
} }
fn document_non_exhaustive(item: &clean::Item) -> impl Display + '_ { fn document_non_exhaustive(item: &clean::Item) -> impl Display {
fmt::from_fn(|f| { fmt::from_fn(|f| {
if item.is_non_exhaustive() { if item.is_non_exhaustive() {
write!( write!(

View file

@ -2,7 +2,6 @@ use std::fmt;
use rinja::Template; use rinja::Template;
use rustc_abi::{Primitive, TagEncoding, Variants}; use rustc_abi::{Primitive, TagEncoding, Variants};
use rustc_data_structures::captures::Captures;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::span_bug; use rustc_middle::span_bug;
use rustc_middle::ty::layout::LayoutError; use rustc_middle::ty::layout::LayoutError;
@ -26,10 +25,7 @@ struct TypeLayoutSize {
size: u64, size: u64,
} }
pub(crate) fn document_type_layout<'a, 'cx: 'a>( pub(crate) fn document_type_layout(cx: &Context<'_>, ty_def_id: DefId) -> impl fmt::Display {
cx: &'a Context<'cx>,
ty_def_id: DefId,
) -> impl fmt::Display + 'a + Captures<'cx> {
fmt::from_fn(move |f| { fmt::from_fn(move |f| {
if !cx.shared.show_type_layout { if !cx.shared.show_type_layout {
return Ok(()); return Ok(());

View file

@ -58,7 +58,7 @@ fn filter_assoc_items_by_name_and_namespace(
assoc_items_of: DefId, assoc_items_of: DefId,
ident: Ident, ident: Ident,
ns: Namespace, ns: Namespace,
) -> impl Iterator<Item = &ty::AssocItem> + '_ { ) -> impl Iterator<Item = &ty::AssocItem> {
tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| { tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| {
item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of) item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of)
}) })