diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f2b9c0bcf3ee7..b6485c61bd2ae 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -140,10 +140,6 @@ impl Buffer { self.for_html } - pub(crate) fn reserve(&mut self, additional: usize) { - self.buffer.reserve(additional) - } - pub(crate) fn len(&self) -> usize { self.buffer.len() } @@ -206,36 +202,20 @@ impl clean::GenericParamDef { f.write_str(self.name.as_str())?; if !bounds.is_empty() { - if f.alternate() { - write!(f, ": {:#}", print_generic_bounds(bounds, cx))?; - } else { - write!(f, ": {}", print_generic_bounds(bounds, cx))?; - } + write!(f, ": {}", print_generic_bounds(bounds, cx))?; } if let Some(ref ty) = default { - if f.alternate() { - write!(f, " = {:#}", ty.print(cx))?; - } else { - write!(f, " = {}", ty.print(cx))?; - } + write!(f, " = {}", ty.print(cx))?; } Ok(()) } clean::GenericParamDefKind::Const { ty, default, .. } => { - if f.alternate() { - write!(f, "const {}: {:#}", self.name, ty.print(cx))?; - } else { - write!(f, "const {}: {}", self.name, ty.print(cx))?; - } + write!(f, "const {}: {}", self.name, ty.print(cx))?; if let Some(default) = default { - if f.alternate() { - write!(f, " = {:#}", default)?; - } else { - write!(f, " = {}", default)?; - } + write!(f, " = {}", default)?; } Ok(()) @@ -256,11 +236,7 @@ impl clean::Generics { return Ok(()); } - if f.alternate() { - write!(f, "<{:#}>", comma_sep(real_params.map(|g| g.print(cx)), true)) - } else { - write!(f, "<{}>", comma_sep(real_params.map(|g| g.print(cx)), true)) - } + write!(f, "<{}>", comma_sep(real_params.map(|g| g.print(cx)), true)) }) } } @@ -285,11 +261,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( !matches!(pred, clean::WherePredicate::BoundPredicate { bounds, .. } if bounds.is_empty()) }).map(|pred| { display_fn(move |f| { - if f.alternate() { - f.write_str(" ")?; - } else { - f.write_str("\n")?; - } + f.write_str("\n")?; match pred { clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { @@ -297,25 +269,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( let generic_bounds = print_generic_bounds(bounds, cx); if bound_params.is_empty() { - if f.alternate() { - write!(f, "{ty_cx:#}: {generic_bounds:#}") - } else { - write!(f, "{ty_cx}: {generic_bounds}") - } + write!(f, "{ty_cx}: {generic_bounds}") } else { - if f.alternate() { - write!( - f, - "for<{:#}> {ty_cx:#}: {generic_bounds:#}", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) - ) - } else { - write!( - f, - "for<{}> {ty_cx}: {generic_bounds}", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) - ) - } + write!( + f, + "for<{}> {ty_cx}: {generic_bounds}", + comma_sep(bound_params.iter().map(|lt| lt.print()), true) + ) } } clean::WherePredicate::RegionPredicate { lifetime, bounds } => { @@ -328,11 +288,7 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( } // FIXME(fmease): Render bound params. clean::WherePredicate::EqPredicate { lhs, rhs, bound_params: _ } => { - if f.alternate() { - write!(f, "{:#} == {:#}", lhs.print(cx), rhs.print(cx)) - } else { - write!(f, "{} == {}", lhs.print(cx), rhs.print(cx)) - } + write!(f, "{} == {}", lhs.print(cx), rhs.print(cx)) } } }) @@ -343,42 +299,34 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( } let where_preds = comma_sep(where_predicates, false); - let clause = if f.alternate() { - if ending == Ending::Newline { - format!(" where{where_preds},") - } else { - format!(" where{where_preds}") - } - } else { - let mut br_with_padding = String::with_capacity(6 * indent + 28); - br_with_padding.push_str("\n"); + let mut br_with_padding = String::with_capacity(6 * indent + 28); + br_with_padding.push_str("\n"); - let padding_amout = - if ending == Ending::Newline { indent + 4 } else { indent + "fn where ".len() }; + let padding_amout = + if ending == Ending::Newline { indent + 4 } else { indent + "fn where ".len() }; - for _ in 0..padding_amout { - br_with_padding.push_str(" "); - } - let where_preds = where_preds.to_string().replace('\n', &br_with_padding); + for _ in 0..padding_amout { + br_with_padding.push_str(" "); + } + let where_preds = where_preds.to_string().replace('\n', &br_with_padding); - if ending == Ending::Newline { - let mut clause = " ".repeat(indent.saturating_sub(1)); - write!(clause, "where{where_preds},")?; - clause + let clause = if ending == Ending::Newline { + let mut clause = " ".repeat(indent.saturating_sub(1)); + write!(clause, "where{where_preds},")?; + clause + } else { + // insert a newline after a single space but before multiple spaces at the start + if indent == 0 { + format!("\nwhere{where_preds}") } else { - // insert a newline after a single space but before multiple spaces at the start - if indent == 0 { - format!("\nwhere{where_preds}") - } else { - // put the first one on the same line as the 'where' keyword - let where_preds = where_preds.replacen(&br_with_padding, " ", 1); + // put the first one on the same line as the 'where' keyword + let where_preds = where_preds.replacen(&br_with_padding, " ", 1); - let mut clause = br_with_padding; - clause.truncate(clause.len() - "where ".len()); + let mut clause = br_with_padding; + clause.truncate(clause.len() - "where ".len()); - write!(clause, "where{where_preds}")?; - clause - } + write!(clause, "where{where_preds}")?; + clause } }; write!(f, "{clause}") @@ -394,11 +342,7 @@ impl clean::Lifetime { impl clean::Constant { pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl fmt::Display + '_ { let expr = self.expr(tcx); - display_fn( - move |f| { - if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) } - }, - ) + display_fn(move |f| write!(f, "{}", Escape(&expr))) } } @@ -409,25 +353,13 @@ impl clean::PolyTrait { ) -> impl fmt::Display + 'a + Captures<'tcx> { display_fn(move |f| { if !self.generic_params.is_empty() { - if f.alternate() { - write!( - f, - "for<{:#}> ", - comma_sep(self.generic_params.iter().map(|g| g.print(cx)), true) - )?; - } else { - write!( - f, - "for<{}> ", - comma_sep(self.generic_params.iter().map(|g| g.print(cx)), true) - )?; - } - } - if f.alternate() { - write!(f, "{:#}", self.trait_.print(cx)) - } else { - write!(f, "{}", self.trait_.print(cx)) + write!( + f, + "for<{}> ", + comma_sep(self.generic_params.iter().map(|g| g.print(cx)), true) + )?; } + write!(f, "{}", self.trait_.print(cx)) }) } } @@ -446,11 +378,7 @@ impl clean::GenericBound { // ~const is experimental; do not display those bounds in rustdoc hir::TraitBoundModifier::MaybeConst => "", }; - if f.alternate() { - write!(f, "{}{:#}", modifier_str, ty.print(cx)) - } else { - write!(f, "{}{}", modifier_str, ty.print(cx)) - } + write!(f, "{}{}", modifier_str, ty.print(cx)) } }) } @@ -465,39 +393,23 @@ impl clean::GenericArgs { match self { clean::GenericArgs::AngleBracketed { args, bindings } => { if !args.is_empty() || !bindings.is_empty() { - if f.alternate() { - f.write_str("<")?; - } else { - f.write_str("<")?; - } + f.write_str("<")?; let mut comma = false; for arg in args.iter() { if comma { f.write_str(", ")?; } comma = true; - if f.alternate() { - write!(f, "{:#}", arg.print(cx))?; - } else { - write!(f, "{}", arg.print(cx))?; - } + write!(f, "{}", arg.print(cx))?; } for binding in bindings.iter() { if comma { f.write_str(", ")?; } comma = true; - if f.alternate() { - write!(f, "{:#}", binding.print(cx))?; - } else { - write!(f, "{}", binding.print(cx))?; - } - } - if f.alternate() { - f.write_str(">")?; - } else { - f.write_str(">")?; + write!(f, "{}", binding.print(cx))?; } + f.write_str(">")?; } } clean::GenericArgs::Parenthesized { inputs, output } => { @@ -508,19 +420,11 @@ impl clean::GenericArgs { f.write_str(", ")?; } comma = true; - if f.alternate() { - write!(f, "{:#}", ty.print(cx))?; - } else { - write!(f, "{}", ty.print(cx))?; - } + write!(f, "{}", ty.print(cx))?; } f.write_str(")")?; if let Some(ref ty) = *output { - if f.alternate() { - write!(f, " -> {:#}", ty.print(cx))?; - } else { - write!(f, " -> {}", ty.print(cx))?; - } + write!(f, " -> {}", ty.print(cx))?; } } } @@ -809,24 +713,20 @@ fn resolved_path<'cx>( write!(w, "{}::", if seg.name == kw::PathRoot { "" } else { seg.name.as_str() })?; } } - if w.alternate() { - write!(w, "{}{:#}", &last.name, last.args.print(cx))?; - } else { - let path = if use_absolute { - if let Ok((_, _, fqp)) = href(did, cx) { - format!( - "{}::{}", - join_with_double_colon(&fqp[..fqp.len() - 1]), - anchor(did, *fqp.last().unwrap(), cx) - ) - } else { - last.name.to_string() - } + let path = if use_absolute { + if let Ok((_, _, fqp)) = href(did, cx) { + format!( + "{}::{}", + join_with_double_colon(&fqp[..fqp.len() - 1]), + anchor(did, *fqp.last().unwrap(), cx) + ) } else { - anchor(did, last.name, cx).to_string() - }; - write!(w, "{}{}", path, last.args.print(cx))?; - } + last.name.to_string() + } + } else { + anchor(did, last.name, cx).to_string() + }; + write!(w, "{}{}", path, last.args.print(cx))?; Ok(()) } @@ -848,50 +748,48 @@ fn primitive_link_fragment( ) -> fmt::Result { let m = &cx.cache(); let mut needs_termination = false; - if !f.alternate() { - match m.primitive_locations.get(&prim) { - Some(&def_id) if def_id.is_local() => { - let len = cx.current.len(); - let len = if len == 0 { 0 } else { len - 1 }; - write!( - f, - "", - "../".repeat(len), - prim.as_sym() - )?; - needs_termination = true; - } - Some(&def_id) => { - let loc = match m.extern_locations[&def_id.krate] { - ExternalLocation::Remote(ref s) => { - let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()); - let builder: UrlPartsBuilder = - [s.as_str().trim_end_matches('/'), cname_sym.as_str()] - .into_iter() - .collect(); - Some(builder) - } - ExternalLocation::Local => { - let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()); - Some(if cx.current.first() == Some(&cname_sym) { - iter::repeat(sym::dotdot).take(cx.current.len() - 1).collect() - } else { - iter::repeat(sym::dotdot) - .take(cx.current.len()) - .chain(iter::once(cname_sym)) - .collect() - }) - } - ExternalLocation::Unknown => None, - }; - if let Some(mut loc) = loc { - loc.push_fmt(format_args!("primitive.{}.html", prim.as_sym())); - write!(f, "", loc.finish())?; - needs_termination = true; + match m.primitive_locations.get(&prim) { + Some(&def_id) if def_id.is_local() => { + let len = cx.current.len(); + let len = if len == 0 { 0 } else { len - 1 }; + write!( + f, + "", + "../".repeat(len), + prim.as_sym() + )?; + needs_termination = true; + } + Some(&def_id) => { + let loc = match m.extern_locations[&def_id.krate] { + ExternalLocation::Remote(ref s) => { + let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()); + let builder: UrlPartsBuilder = + [s.as_str().trim_end_matches('/'), cname_sym.as_str()] + .into_iter() + .collect(); + Some(builder) + } + ExternalLocation::Local => { + let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()); + Some(if cx.current.first() == Some(&cname_sym) { + iter::repeat(sym::dotdot).take(cx.current.len() - 1).collect() + } else { + iter::repeat(sym::dotdot) + .take(cx.current.len()) + .chain(iter::once(cname_sym)) + .collect() + }) } + ExternalLocation::Unknown => None, + }; + if let Some(mut loc) = loc { + loc.push_fmt(format_args!("primitive.{}.html", prim.as_sym())); + write!(f, "", loc.finish())?; + needs_termination = true; } - None => {} } + None => {} } write!(f, "{}", name)?; if needs_termination { @@ -955,7 +853,7 @@ fn fmt_type<'cx>( trace!("fmt_type(t = {:?})", t); match *t { - clean::Generic(name) => write!(f, "{}", name), + clean::Generic(name) => write!(f, "{}", Escape(name.as_str())), clean::Type::Path { ref path } => { // Paths like `T::Output` and `Self::Output` should be rendered with all segments. let did = path.def_id(); @@ -971,96 +869,69 @@ fn fmt_type<'cx>( } clean::Primitive(prim) => primitive_link(f, prim, prim.as_sym().as_str(), cx), clean::BareFunction(ref decl) => { - if f.alternate() { - write!( - f, - "{:#}{}{:#}fn{:#}", - decl.print_hrtb_with_space(cx), - decl.unsafety.print_with_space(), - print_abi_with_space(decl.abi), - decl.decl.print(cx), - ) - } else { - write!( - f, - "{}{}{}", - decl.print_hrtb_with_space(cx), - decl.unsafety.print_with_space(), - print_abi_with_space(decl.abi) - )?; - primitive_link(f, PrimitiveType::Fn, "fn", cx)?; - write!(f, "{}", decl.decl.print(cx)) - } + write!( + f, + "{}{}{}", + decl.print_hrtb_with_space(cx), + decl.unsafety.print_with_space(), + print_abi_with_space(decl.abi) + )?; + primitive_link(f, PrimitiveType::Fn, "fn", cx)?; + write!(f, "{}", decl.decl.print(cx)) } - clean::Tuple(ref typs) => { - match &typs[..] { - &[] => primitive_link(f, PrimitiveType::Unit, "()", cx), - [one] => { - if let clean::Generic(name) = one { - primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx) - } else { - write!(f, "(")?; - // Carry `f.alternate()` into this display w/o branching manually. - fmt::Display::fmt(&one.print(cx), f)?; - write!(f, ",)") - } + clean::Tuple(ref typs) => match &typs[..] { + &[] => primitive_link(f, PrimitiveType::Unit, "()", cx), + [one] => { + if let clean::Generic(name) = one { + primitive_link(f, PrimitiveType::Tuple, &format!("({name},)"), cx) + } else { + write!(f, "({},)", &one.print(cx)) } - many => { - let generic_names: Vec = many - .iter() - .filter_map(|t| match t { - clean::Generic(name) => Some(*name), - _ => None, - }) - .collect(); - let is_generic = generic_names.len() == many.len(); - if is_generic { - primitive_link( - f, - PrimitiveType::Tuple, - &format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")), - cx, - ) - } else { - write!(f, "(")?; - for (i, item) in many.iter().enumerate() { - if i != 0 { - write!(f, ", ")?; - } - // Carry `f.alternate()` into this display w/o branching manually. - fmt::Display::fmt(&item.print(cx), f)?; + } + many => { + let generic_names: Vec = many + .iter() + .filter_map(|t| match t { + clean::Generic(name) => Some(*name), + _ => None, + }) + .collect(); + let is_generic = generic_names.len() == many.len(); + if is_generic { + primitive_link( + f, + PrimitiveType::Tuple, + &format!("({})", generic_names.iter().map(|s| s.as_str()).join(", ")), + cx, + ) + } else { + write!(f, "(")?; + for (i, item) in many.iter().enumerate() { + if i != 0 { + write!(f, ", ")?; } - write!(f, ")") + write!(f, "{}", &item.print(cx))?; } + write!(f, ")") } } - } + }, clean::Slice(ref t) => match **t { clean::Generic(name) => { primitive_link(f, PrimitiveType::Slice, &format!("[{name}]"), cx) } - _ => { - write!(f, "[")?; - fmt::Display::fmt(&t.print(cx), f)?; - write!(f, "]") - } + _ => write!(f, "[{}]", &t.print(cx)), }, clean::Array(ref t, ref n) => match **t { - clean::Generic(name) if !f.alternate() => primitive_link( + clean::Generic(name) => primitive_link( f, PrimitiveType::Array, &format!("[{name}; {n}]", n = Escape(n)), cx, ), _ => { - write!(f, "[")?; - fmt::Display::fmt(&t.print(cx), f)?; - if f.alternate() { - write!(f, "; {n}")?; - } else { - write!(f, "; ")?; - primitive_link(f, PrimitiveType::Array, &format!("{n}", n = Escape(n)), cx)?; - } + write!(f, "[{}; ", &t.print(cx))?; + primitive_link(f, PrimitiveType::Array, &format!("{n}", n = Escape(n)), cx)?; write!(f, "]") } }, @@ -1071,11 +942,7 @@ fn fmt_type<'cx>( }; if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() { - let text = if f.alternate() { - format!("*{} {:#}", m, t.print(cx)) - } else { - format!("*{} {}", m, t.print(cx)) - }; + let text = format!("*{} {}", m, t.print(cx)); primitive_link(f, clean::PrimitiveType::RawPointer, &text, cx) } else { primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{} ", m), cx)?; @@ -1088,7 +955,7 @@ fn fmt_type<'cx>( _ => String::new(), }; let m = mutability.print_with_space(); - let amp = if f.alternate() { "&" } else { "&" }; + let amp = "&"; match **ty { clean::DynTrait(ref bounds, ref trait_lt) if bounds.len() > 1 || trait_lt.is_some() => @@ -1107,11 +974,7 @@ fn fmt_type<'cx>( } } clean::ImplTrait(ref bounds) => { - if f.alternate() { - write!(f, "impl {:#}", print_generic_bounds(bounds, cx)) - } else { - write!(f, "impl {}", print_generic_bounds(bounds, cx)) - } + write!(f, "impl {}", print_generic_bounds(bounds, cx)) } clean::QPath(box clean::QPathData { ref assoc, @@ -1119,19 +982,11 @@ fn fmt_type<'cx>( ref trait_, should_show_cast, }) => { - if f.alternate() { - if should_show_cast { - write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))? - } else { - write!(f, "{:#}::", self_type.print(cx))? - } + if should_show_cast { + write!(f, "<{} as {}>::", self_type.print(cx), trait_.print(cx))? } else { - if should_show_cast { - write!(f, "<{} as {}>::", self_type.print(cx), trait_.print(cx))? - } else { - write!(f, "{}::", self_type.print(cx))? - } - }; + write!(f, "{}::", self_type.print(cx))? + } // It's pretty unsightly to look at `::C` in output, and // we've got hyperlinking on our side, so try to avoid longer // notation as much as possible by making `C` a hyperlink to trait @@ -1143,7 +998,7 @@ fn fmt_type<'cx>( // everything comes in as a fully resolved QPath (hard to // look at). match href(trait_.def_id(), cx) { - Ok((ref url, _, ref path)) if !f.alternate() => { + Ok((ref url, _, ref path)) => { write!( f, " impl fmt::Display + 'b + Captures<'tcx> { display_fn(move |f| fmt_type(self, f, false, cx)) } + + /// Emit this type in plain text form (no HTML). + pub(crate) fn print_plain<'b, 'a: 'b, 'tcx: 'a>( + &'a self, + cx: &'a Context<'tcx>, + ) -> impl fmt::Display + 'b + Captures<'tcx> { + Plain(self.print(cx)) + } } impl clean::Path { @@ -1178,6 +1041,14 @@ impl clean::Path { ) -> impl fmt::Display + 'b + Captures<'tcx> { display_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx)) } + + /// Emit this type in plain text form (no HTML). + pub(crate) fn print_plain<'b, 'a: 'b, 'tcx: 'a>( + &'a self, + cx: &'a Context<'tcx>, + ) -> impl fmt::Display + 'b + Captures<'tcx> { + Plain(self.print(cx)) + } } impl clean::Impl { @@ -1187,11 +1058,7 @@ impl clean::Impl { cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { display_fn(move |f| { - if f.alternate() { - write!(f, "impl{:#} ", self.generics.print(cx))?; - } else { - write!(f, "impl{} ", self.generics.print(cx))?; - } + write!(f, "impl{} ", self.generics.print(cx))?; if let Some(ref ty) = self.trait_ { match self.polarity { @@ -1219,17 +1086,10 @@ impl clean::Impl { let hrtb = bare_fn.print_hrtb_with_space(cx); let unsafety = bare_fn.unsafety.print_with_space(); let abi = print_abi_with_space(bare_fn.abi); - if f.alternate() { - write!( - f, - "{hrtb:#}{unsafety}{abi:#}", - )?; - } else { - write!( - f, - "{hrtb}{unsafety}{abi}", - )?; - } + write!( + f, + "{hrtb}{unsafety}{abi}", + )?; let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { @@ -1260,13 +1120,7 @@ impl clean::Arguments { ) -> impl fmt::Display + 'a + Captures<'tcx> { display_fn(move |f| { for (i, input) in self.values.iter().enumerate() { - write!(f, "{}: ", input.name)?; - - if f.alternate() { - write!(f, "{:#}", input.type_.print(cx))?; - } else { - write!(f, "{}", input.type_.print(cx))?; - } + write!(f, "{}: {}", input.name, input.type_.print(cx))?; if i + 1 < self.values.len() { write!(f, ", ")?; } @@ -1283,9 +1137,6 @@ impl clean::FnRetTy { ) -> impl fmt::Display + 'a + Captures<'tcx> { display_fn(move |f| match self { clean::Return(clean::Tuple(tys)) if tys.is_empty() => Ok(()), - clean::Return(ty) if f.alternate() => { - write!(f, " -> {:#}", ty.print(cx)) - } clean::Return(ty) => write!(f, " -> {}", ty.print(cx)), clean::DefaultReturn => Ok(()), }) @@ -1311,7 +1162,99 @@ impl clean::BareFunctionDecl { } } -// Implements Write but only counts the bytes "written". +/// This is a simplified HTML processor, intended for counting the number of characters +/// of text that a stream of HTML is equivalent to. This is used to calculate the width +/// (in characters) of a function declaration, to decide whether to line-wrap it like +/// rustfmt would do. It's only valid for use with HTML emitted from within this module, +/// so it is intentionally not pub(crate). +/// +/// This makes some assumptions that are specifically tied to the HTML emitted in format.rs: +/// - Whitespace is significant. +/// - All tags display their contents as text. +/// - Each call to write() contains a sequence of bytes that is valid UTF-8 on its own. +/// - All '<' in HTML attributes are escaped. +/// - HTML attributes are quoted with double quotes. +/// - The only HTML entities used are `<`, `>`, `&`, `"`, and `'` +#[derive(Debug, Clone)] +pub(super) struct HtmlRemover { + inner: W, + state: HtmlTextCounterState, +} + +impl HtmlRemover { + pub(super) fn new(w: W) -> Self { + HtmlRemover { inner: w, state: HtmlTextCounterState::Text } + } + + #[cfg(test)] + pub(super) fn into_inner(self) -> W { + self.inner + } +} + +// A state machine that tracks our progress through the HTML. +#[derive(Debug, Clone)] +enum HtmlTextCounterState { + Text, + // A small buffer to store the entity name + Entity(u8, [u8; 4]), + Tag, +} + +impl fmt::Write for HtmlRemover { + fn write_str(&mut self, s: &str) -> fmt::Result { + use HtmlTextCounterState::*; + for c in s.chars() { + match (&mut self.state, c) { + (Text, '<') => self.state = Tag, + (Text, '&') => self.state = Entity(0, Default::default()), + (Text, _) => write!(self.inner, "{c}")?, + // Note: `>` can occur in attribute values, but we always escape + // them internally, so we don't have to have an extra state for + // "in attribute value." + // https://www.w3.org/TR/2011/WD-html5-20110525/syntax.html#syntax-attributes + (Tag, '>') => self.state = Text, + (Tag, '<') => Err(fmt::Error)?, + // Within a tag, do nothing. + (Tag, _) => {} + // Finish an entity + (Entity(len, arr), ';') => { + let emit = match std::str::from_utf8(&arr[0..*len as usize]).unwrap() { + "lt" => '<', + "gt" => '>', + "amp" => '&', + "quot" => '"', + "#39" => '\'', + _ => Err(fmt::Error)?, + }; + write!(self.inner, "{emit}")?; + self.state = Text; + } + // Read one character of an entity name + (Entity(ref mut len, ref mut arr), c) => { + if *len as usize > arr.len() - 1 { + Err(fmt::Error)?; + } + arr[*len as usize] = c as u8; + *len += 1; + } + } + } + Ok(()) + } +} + +/// This generates the plain text form of a marked-up HTML input, using HtmlRemover. +pub(super) struct Plain(pub(super) D); + +impl fmt::Display for Plain { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut remover = HtmlRemover::new(f); + write!(&mut remover, "{}", self.0) + } +} + +/// Implements Write but only counts the bytes "written". struct WriteCounter(usize); impl std::fmt::Write for WriteCounter { @@ -1321,7 +1264,7 @@ impl std::fmt::Write for WriteCounter { } } -// Implements Display by emitting the given number of spaces. +/// Implements Display by emitting the given number of spaces. struct Indent(usize); impl fmt::Display for Indent { @@ -1340,48 +1283,34 @@ impl clean::FnDecl { ) -> impl fmt::Display + 'b + Captures<'tcx> { display_fn(move |f| { let ellipsis = if self.c_variadic { ", ..." } else { "" }; - if f.alternate() { - write!( - f, - "({args:#}{ellipsis}){arrow:#}", - args = self.inputs.print(cx), - ellipsis = ellipsis, - arrow = self.output.print(cx) - ) - } else { - write!( - f, - "({args}{ellipsis}){arrow}", - args = self.inputs.print(cx), - ellipsis = ellipsis, - arrow = self.output.print(cx) - ) - } + write!( + f, + "({args}{ellipsis}){arrow}", + args = self.inputs.print(cx), + ellipsis = ellipsis, + arrow = self.output.print(cx) + ) }) } - /// * `header_len`: The length of the function header and name. In other words, the number of - /// characters in the function declaration up to but not including the parentheses. - /// This is expected to go into a `
`/`code-header` block, so indentation and newlines
-    ///   are preserved.
+    /// * `header`: Prints the function header and name (everything before the params).
     /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
     ///   necessary.
     pub(crate) fn full_print<'a, 'tcx: 'a>(
         &'a self,
-        header_len: usize,
+        header: impl fmt::Display + 'a,
         indent: usize,
         cx: &'a Context<'tcx>,
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
         display_fn(move |f| {
             // First, generate the text form of the declaration, with no line wrapping, and count the bytes.
+            let header = Plain(header);
+            let decl = Plain(display_fn(|f| self.inner_full_print(None, f, cx)));
             let mut counter = WriteCounter(0);
-            write!(&mut counter, "{:#}", display_fn(|f| { self.inner_full_print(None, f, cx) }))
-                .unwrap();
+            write!(&mut counter, "{header}{decl}")?;
             // If the text form was over 80 characters wide, we will line-wrap our output.
-            let line_wrapping_indent =
-                if header_len + counter.0 > 80 { Some(indent) } else { None };
-            // Generate the final output. This happens to accept `{:#}` formatting to get textual
-            // output but in practice it is only formatted with `{}` to get HTML output.
+            let line_wrapping_indent = (counter.0 > 80).then_some(indent);
+            // Generate the final output.
             self.inner_full_print(line_wrapping_indent, f, cx)
         })
     }
@@ -1394,7 +1323,7 @@ impl clean::FnDecl {
         f: &mut fmt::Formatter<'_>,
         cx: &Context<'_>,
     ) -> fmt::Result {
-        let amp = if f.alternate() { "&" } else { "&" };
+        let amp = "&";
 
         write!(f, "(")?;
         if let Some(n) = line_wrapping_indent {
@@ -1419,16 +1348,14 @@ impl clean::FnDecl {
                         write!(f, "{}{}self", amp, mtbl.print_with_space())?;
                     }
                     clean::SelfExplicit(ref typ) => {
-                        write!(f, "self: ")?;
-                        fmt::Display::fmt(&typ.print(cx), f)?;
+                        write!(f, "self: {}", typ.print(cx))?;
                     }
                 }
             } else {
                 if input.is_const {
                     write!(f, "const ")?;
                 }
-                write!(f, "{}: ", input.name)?;
-                fmt::Display::fmt(&input.type_.print(cx), f)?;
+                write!(f, "{}: {}", input.name, input.type_.print(cx))?;
             }
         }
 
@@ -1444,7 +1371,7 @@ impl clean::FnDecl {
             Some(n) => write!(f, "\n{})", Indent(n))?,
         };
 
-        fmt::Display::fmt(&self.output.print(cx), f)?;
+        write!(f, "{}", self.output.print(cx))?;
         Ok(())
     }
 }
@@ -1630,26 +1557,14 @@ impl clean::TypeBinding {
     ) -> impl fmt::Display + 'a + Captures<'tcx> {
         display_fn(move |f| {
             f.write_str(self.assoc.name.as_str())?;
-            if f.alternate() {
-                write!(f, "{:#}", self.assoc.args.print(cx))?;
-            } else {
-                write!(f, "{}", self.assoc.args.print(cx))?;
-            }
+            write!(f, "{}", self.assoc.args.print(cx))?;
             match self.kind {
                 clean::TypeBindingKind::Equality { ref term } => {
-                    if f.alternate() {
-                        write!(f, " = {:#}", term.print(cx))?;
-                    } else {
-                        write!(f, " = {}", term.print(cx))?;
-                    }
+                    write!(f, " = {}", term.print(cx))?;
                 }
                 clean::TypeBindingKind::Constraint { ref bounds } => {
                     if !bounds.is_empty() {
-                        if f.alternate() {
-                            write!(f, ": {:#}", print_generic_bounds(bounds, cx))?;
-                        } else {
-                            write!(f, ": {}", print_generic_bounds(bounds, cx))?;
-                        }
+                        write!(f, ": {}", print_generic_bounds(bounds, cx))?;
                     }
                 }
             }
@@ -1659,12 +1574,9 @@ impl clean::TypeBinding {
 }
 
 pub(crate) fn print_abi_with_space(abi: Abi) -> impl fmt::Display {
-    display_fn(move |f| {
-        let quot = if f.alternate() { "\"" } else { """ };
-        match abi {
-            Abi::Rust => Ok(()),
-            abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()),
-        }
+    display_fn(move |f| match abi {
+        Abi::Rust => Ok(()),
+        abi => write!(f, "extern \"{}\" ", abi.name()),
     })
 }
 
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index d75d03071f892..08d23b9531417 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -809,7 +809,7 @@ fn assoc_method(
 ) {
     let tcx = cx.tcx();
     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().as_str();
     let vis = visibility_print_with_space(meth.visibility(tcx), meth.item_id, cx).to_string();
     // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove
     // this condition.
@@ -825,22 +825,13 @@ fn assoc_method(
     let abi = print_abi_with_space(header.abi).to_string();
     let href = assoc_href_attr(meth, link, cx);
 
-    // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
-    let generics_len = format!("{:#}", g.print(cx)).len();
-    let mut header_len = "fn ".len()
-        + vis.len()
-        + constness.len()
-        + asyncness.len()
-        + unsafety.len()
-        + defaultness.len()
-        + abi.len()
-        + name.as_str().len()
-        + generics_len;
-
-    let notable_traits = d.output.as_return().and_then(|output| notable_traits_button(output, cx));
+    let notable_traits = d
+        .output
+        .as_return()
+        .and_then(|output| notable_traits_button(output, cx))
+        .unwrap_or_default();
 
     let (indent, indent_str, end_newline) = if parent == ItemType::Trait {
-        header_len += 4;
         let indent_str = "    ";
         render_attributes_in_pre(w, meth, indent_str);
         (4, indent_str, Ending::NoNewline)
@@ -848,25 +839,39 @@ fn assoc_method(
         render_attributes_in_code(w, meth);
         (0, "", Ending::Newline)
     };
-    w.reserve(header_len + "{".len() + "".len());
-    write!(
-        w,
-        "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn {name}\
-         {generics}{decl}{notable_traits}{where_clause}",
-        indent = indent_str,
-        vis = vis,
-        constness = constness,
-        asyncness = asyncness,
-        unsafety = unsafety,
-        defaultness = defaultness,
-        abi = abi,
-        href = href,
-        name = name,
-        generics = g.print(cx),
-        decl = d.full_print(header_len, indent, cx),
-        notable_traits = notable_traits.unwrap_or_default(),
-        where_clause = print_where_clause(g, cx, indent, end_newline),
-    );
+
+    let fn_header = FunctionHeader {
+        indent_str,
+        vis,
+        constness,
+        asyncness,
+        unsafety,
+        defaultness,
+        abi,
+        href,
+        name,
+        generics: g.print(cx).to_string(),
+    };
+
+    let decl = d.full_print(&fn_header, indent, cx);
+    let where_clause = print_where_clause(g, cx, indent, end_newline);
+
+    write!(w, "{fn_header}{decl}{notable_traits}{where_clause}");
+}
+
+#[derive(Template)]
+#[template(path = "function_header.html")]
+struct FunctionHeader<'a> {
+    indent_str: &'static str,
+    vis: String,
+    constness: &'a str,
+    asyncness: &'a str,
+    unsafety: &'a str,
+    defaultness: &'a str,
+    abi: String,
+    href: String,
+    name: &'a str,
+    generics: String,
 }
 
 /// Writes a span containing the versions at which an item became stable and/or const-stable. For
@@ -1141,8 +1146,10 @@ fn render_assoc_items_inner(
                 (RenderMode::Normal, "implementations-list".to_owned())
             }
             AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
-                let id =
-                    cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
+                let id = cx.derive_id(small_url_encode(format!(
+                    "deref-methods-{}",
+                    type_.print_plain(cx)
+                )));
                 if let Some(def_id) = type_.def_id(cx.cache()) {
                     cx.deref_id_map.insert(def_id, id.clone());
                 }
@@ -1314,7 +1321,7 @@ pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> O
         cx.types_with_notable_traits.insert(ty.clone());
         Some(format!(
             " ",
-            ty = Escape(&format!("{:#}", ty.print(cx))),
+            ty = Escape(&ty.print_plain(cx).to_string()),
         ))
     } else {
         None
@@ -1379,7 +1386,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
         write!(&mut out, "
",); } - (format!("{:#}", ty.print(cx)), out.into_inner()) + (ty.print_plain(cx).to_string(), out.into_inner()) } pub(crate) fn notable_traits_json<'a>( @@ -1947,20 +1954,18 @@ pub(crate) fn small_url_encode(s: String) -> String { fn get_id_for_impl(for_: &clean::Type, trait_: Option<&clean::Path>, cx: &Context<'_>) -> String { match trait_ { - Some(t) => small_url_encode(format!("impl-{:#}-for-{:#}", t.print(cx), for_.print(cx))), - None => small_url_encode(format!("impl-{:#}", for_.print(cx))), + Some(t) => { + small_url_encode(format!("impl-{}-for-{}", t.print_plain(cx), for_.print_plain(cx))) + } + None => small_url_encode(format!("impl-{}", for_.print_plain(cx))), } } fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> { match *item.kind { - clean::ItemKind::ImplItem(ref i) => { - i.trait_.as_ref().map(|trait_| { - // Alternative format produces no URLs, - // so this parameter does nothing. - (format!("{:#}", i.for_.print(cx)), get_id_for_impl(&i.for_, Some(trait_), cx)) - }) - } + clean::ItemKind::ImplItem(ref i) => i.trait_.as_ref().map(|trait_| { + (i.for_.print_plain(cx).to_string(), get_id_for_impl(&i.for_, Some(trait_), cx)) + }), _ => None, } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 7eb9c0b7cf52a..9f7b92201c9ca 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -528,39 +528,34 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle let abi = print_abi_with_space(header.abi).to_string(); let asyncness = header.asyncness.print_with_space(); let visibility = visibility_print_with_space(it.visibility(tcx), it.item_id, cx).to_string(); - let name = it.name.unwrap(); - - let generics_len = format!("{:#}", f.generics.print(cx)).len(); - let header_len = "fn ".len() - + visibility.len() - + constness.len() - + asyncness.len() - + unsafety.len() - + abi.len() - + name.as_str().len() - + generics_len; + let name = it.name.as_ref().unwrap().as_str(); + + let fn_header = super::FunctionHeader { + indent_str: "", + vis: visibility, + constness, + asyncness, + unsafety, + // standalone functions are never default, only associated functions. + defaultness: "", + abi, + href: "".to_string(), + name, + generics: f.generics.print(cx).to_string(), + }; - let notable_traits = - f.decl.output.as_return().and_then(|output| notable_traits_button(output, cx)); + let notable_traits = f + .decl + .output + .as_return() + .and_then(|output| notable_traits_button(output, cx)) + .unwrap_or_default(); wrap_item(w, |w| { render_attributes_in_pre(w, it, ""); - w.reserve(header_len); - write!( - w, - "{vis}{constness}{asyncness}{unsafety}{abi}fn \ - {name}{generics}{decl}{notable_traits}{where_clause}", - vis = visibility, - constness = constness, - asyncness = asyncness, - unsafety = unsafety, - abi = abi, - name = name, - generics = f.generics.print(cx), - where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline), - decl = f.decl.full_print(header_len, 0, cx), - notable_traits = notable_traits.unwrap_or_default(), - ); + let decl = f.decl.full_print(&fn_header, 0, cx); + let where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline); + write!(w, "{fn_header}{decl}{notable_traits}{where_clause}"); }); document(w, cx, it, None, HeadingOffset::H2); } diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 94ad4753d7cb6..3237a0b6e70e1 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -378,9 +378,9 @@ fn sidebar_deref_methods<'a>( Cow::Borrowed("deref-methods") }; let title = format!( - "Methods from {:#}", - impl_.inner_impl().trait_.as_ref().unwrap().print(cx), - real_target.print(cx), + "Methods from {}", + impl_.inner_impl().trait_.as_ref().unwrap().print_plain(cx), + real_target.print_plain(cx), ); // We want links' order to be reproducible so we don't use unstable sort. ret.sort(); @@ -487,7 +487,7 @@ fn sidebar_render_assoc_items( ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "", ty::ImplPolarity::Negative => "!", }; - let generated = Link::new(encoded, format!("{prefix}{:#}", trait_.print(cx))); + let generated = Link::new(encoded, format!("{prefix}{}", trait_.print_plain(cx))); if links.insert(generated.clone()) { Some(generated) } else { None } }) .collect::>>(); diff --git a/src/librustdoc/html/templates/function_header.html b/src/librustdoc/html/templates/function_header.html new file mode 100644 index 0000000000000..6d17dfa1efdf5 --- /dev/null +++ b/src/librustdoc/html/templates/function_header.html @@ -0,0 +1,11 @@ +{# All of the parts of a function or method declaration that + come before the parameters and return value #} +{{indent_str}} +{{vis|safe}} +{{constness}} +{{asyncness}} +{{unsafety}} +{{defaultness}} +{{abi|safe}} +fn {{name}} +{{generics|safe}} diff --git a/src/librustdoc/html/tests.rs b/src/librustdoc/html/tests.rs index 437d3995e29fc..cfcbbcd7edc0e 100644 --- a/src/librustdoc/html/tests.rs +++ b/src/librustdoc/html/tests.rs @@ -48,3 +48,37 @@ fn href_relative_parts_root() { let fqp = &[sym::std]; assert_relative_path(&[sym::std], relative_to_fqp, fqp); } + +#[test] +fn test_html_remover() { + use super::format::HtmlRemover; + use std::fmt::Write; + + fn assert_removed_eq(input: &str, output: &str) { + let mut remover = HtmlRemover::new(String::new()); + write!(&mut remover, "{}", input).unwrap(); + assert_eq!(&remover.into_inner(), output); + } + + assert_removed_eq("ab", "ab"); + assert_removed_eq("alpha <bet>", "alpha "); + assert_removed_eq("", ""); + assert_removed_eq(">text<", ">text<"); + assert_removed_eq(""'", "\"'"); + + let mut remover = HtmlRemover::new(String::new()); + assert!(write!(&mut remover, "&ent;").is_err()); + + let mut remover = HtmlRemover::new(String::new()); + assert!(write!(&mut remover, "&longentity").is_err()); + + let mut remover = HtmlRemover::new(String::new()); + assert!(write!(&mut remover, "alpha <bet>"); + assert_eq!(&d.to_string(), "alpha "); +} diff --git a/tests/rustdoc/array-links.link_box_generic.html b/tests/rustdoc/array-links.link_box_generic.html index 3481bb6a02547..1631f9988f7b0 100644 --- a/tests/rustdoc/array-links.link_box_generic.html +++ b/tests/rustdoc/array-links.link_box_generic.html @@ -1 +1 @@ -pub fn delta<T>() -> MyBox<[T; 1]> \ No newline at end of file +pub fn delta<T>() -> MyBox<[T; 1]> \ No newline at end of file diff --git a/tests/rustdoc/array-links.link_box_u32.html b/tests/rustdoc/array-links.link_box_u32.html index e864ae55c9f4b..07715fe7fe15c 100644 --- a/tests/rustdoc/array-links.link_box_u32.html +++ b/tests/rustdoc/array-links.link_box_u32.html @@ -1 +1 @@ -pub fn gamma() -> MyBox<[u32; 1]> \ No newline at end of file +pub fn gamma() -> MyBox<[u32; 1]> \ No newline at end of file diff --git a/tests/rustdoc/array-links.link_slice_generic.html b/tests/rustdoc/array-links.link_slice_generic.html index f1ca2f59bd7ca..6db4cf262d17d 100644 --- a/tests/rustdoc/array-links.link_slice_generic.html +++ b/tests/rustdoc/array-links.link_slice_generic.html @@ -1 +1 @@ -pub fn beta<T>() -> &'static [T; 1] \ No newline at end of file +pub fn beta<T>() -> &'static [T; 1] \ No newline at end of file diff --git a/tests/rustdoc/array-links.link_slice_u32.html b/tests/rustdoc/array-links.link_slice_u32.html index c3943e8d32122..c5b624ae3698c 100644 --- a/tests/rustdoc/array-links.link_slice_u32.html +++ b/tests/rustdoc/array-links.link_slice_u32.html @@ -1 +1 @@ -pub fn alpha() -> &'static [u32; 1] \ No newline at end of file +pub fn alpha() -> &'static [u32; 1] \ No newline at end of file diff --git a/tests/rustdoc/nested-modules.rs b/tests/rustdoc/nested-modules.rs index 12234d2cf7ef5..4ed95cb04a8a4 100644 --- a/tests/rustdoc/nested-modules.rs +++ b/tests/rustdoc/nested-modules.rs @@ -7,11 +7,11 @@ mod a_module { pub mod a_nested_module { // @has aCrate/a_nested_module/index.html '//a[@href="fn.a_nested_public_function.html"]' 'a_nested_public_function' - // @hasraw aCrate/a_nested_module/fn.a_nested_public_function.html 'pub fn a_nested_public_function()' + // @has aCrate/a_nested_module/fn.a_nested_public_function.html '//' 'pub fn a_nested_public_function()' pub fn a_nested_public_function() {} // @has aCrate/a_nested_module/index.html '//a[@href="fn.another_nested_public_function.html"]' 'another_nested_public_function' - // @hasraw aCrate/a_nested_module/fn.another_nested_public_function.html 'pub fn another_nested_public_function()' + // @has aCrate/a_nested_module/fn.another_nested_public_function.html '//' 'pub fn another_nested_public_function()' pub use a_nested_module::a_nested_public_function as another_nested_public_function; } diff --git a/tests/rustdoc/reexports-priv.rs b/tests/rustdoc/reexports-priv.rs index 571d7f06fdc62..84ea4ad2c9ef3 100644 --- a/tests/rustdoc/reexports-priv.rs +++ b/tests/rustdoc/reexports-priv.rs @@ -98,7 +98,7 @@ pub mod outer { pub use reexports::foo; // @has 'foo/outer/inner/fn.foo_crate.html' '//pre[@class="rust item-decl"]' 'pub(crate) fn foo_crate()' pub(crate) use reexports::foo_crate; - // @has 'foo/outer/inner/fn.foo_super.html' '//pre[@class="rust item-decl"]' 'pub(in outer) fn foo_super( )' + // @has 'foo/outer/inner/fn.foo_super.html' '//pre[@class="rust item-decl"]' 'pub(in outer) fn foo_super()' pub(super) use::reexports::foo_super; // @!has 'foo/outer/inner/fn.foo_self.html' pub(self) use reexports::foo_self; diff --git a/tests/rustdoc/slice-links.link_box_generic.html b/tests/rustdoc/slice-links.link_box_generic.html index 38aaf20808cf1..0ffbdadd4c62e 100644 --- a/tests/rustdoc/slice-links.link_box_generic.html +++ b/tests/rustdoc/slice-links.link_box_generic.html @@ -1 +1 @@ -pub fn delta<T>() -> MyBox<[T]> \ No newline at end of file +pub fn delta<T>() -> MyBox<[T]> \ No newline at end of file diff --git a/tests/rustdoc/slice-links.link_box_u32.html b/tests/rustdoc/slice-links.link_box_u32.html index 7bec7582df7c9..5c0f2d86f16e0 100644 --- a/tests/rustdoc/slice-links.link_box_u32.html +++ b/tests/rustdoc/slice-links.link_box_u32.html @@ -1 +1 @@ -pub fn gamma() -> MyBox<[u32]> \ No newline at end of file +pub fn gamma() -> MyBox<[u32]> \ No newline at end of file diff --git a/tests/rustdoc/slice-links.link_slice_generic.html b/tests/rustdoc/slice-links.link_slice_generic.html index 1d0f2bf75a233..1c6e1fee2491c 100644 --- a/tests/rustdoc/slice-links.link_slice_generic.html +++ b/tests/rustdoc/slice-links.link_slice_generic.html @@ -1 +1 @@ -pub fn beta<T>() -> &'static [T] \ No newline at end of file +pub fn beta<T>() -> &'static [T] \ No newline at end of file diff --git a/tests/rustdoc/slice-links.link_slice_u32.html b/tests/rustdoc/slice-links.link_slice_u32.html index c86d383042615..461277da65208 100644 --- a/tests/rustdoc/slice-links.link_slice_u32.html +++ b/tests/rustdoc/slice-links.link_slice_u32.html @@ -1 +1 @@ -pub fn alpha() -> &'static [u32] \ No newline at end of file +pub fn alpha() -> &'static [u32] \ No newline at end of file diff --git a/tests/rustdoc/tuples.link1_i32.html b/tests/rustdoc/tuples.link1_i32.html index 4efde28ed52e7..6a7ae03d2df3f 100644 --- a/tests/rustdoc/tuples.link1_i32.html +++ b/tests/rustdoc/tuples.link1_i32.html @@ -1 +1 @@ -pub fn tuple1(x: (i32,)) -> (i32,) \ No newline at end of file +pub fn tuple1(x: (i32,)) -> (i32,) \ No newline at end of file diff --git a/tests/rustdoc/tuples.link1_t.html b/tests/rustdoc/tuples.link1_t.html index 1cbaec05733b5..0a2b164c01ac2 100644 --- a/tests/rustdoc/tuples.link1_t.html +++ b/tests/rustdoc/tuples.link1_t.html @@ -1 +1 @@ -pub fn tuple1_t<T>(x: (T,)) -> (T,) \ No newline at end of file +pub fn tuple1_t<T>(x: (T,)) -> (T,) \ No newline at end of file diff --git a/tests/rustdoc/tuples.link2_i32.html b/tests/rustdoc/tuples.link2_i32.html index 77c8d81b842df..78bef8d617a1f 100644 --- a/tests/rustdoc/tuples.link2_i32.html +++ b/tests/rustdoc/tuples.link2_i32.html @@ -1 +1 @@ -pub fn tuple2(x: (i32, i32)) -> (i32, i32) \ No newline at end of file +pub fn tuple2(x: (i32, i32)) -> (i32, i32) \ No newline at end of file diff --git a/tests/rustdoc/tuples.link2_t.html b/tests/rustdoc/tuples.link2_t.html index 2477aa6be9d39..5779a24b1abcc 100644 --- a/tests/rustdoc/tuples.link2_t.html +++ b/tests/rustdoc/tuples.link2_t.html @@ -1 +1 @@ -pub fn tuple2_t<T>(x: (T, T)) -> (T, T) \ No newline at end of file +pub fn tuple2_t<T>(x: (T, T)) -> (T, T) \ No newline at end of file diff --git a/tests/rustdoc/tuples.link2_tu.html b/tests/rustdoc/tuples.link2_tu.html index b02f8dd8d6530..68d586b568b45 100644 --- a/tests/rustdoc/tuples.link2_tu.html +++ b/tests/rustdoc/tuples.link2_tu.html @@ -1 +1 @@ -pub fn tuple2_tu<T, U>(x: (T, U)) -> (T, U) \ No newline at end of file +pub fn tuple2_tu<T, U>(x: (T, U)) -> (T, U) \ No newline at end of file diff --git a/tests/rustdoc/tuples.link_unit.html b/tests/rustdoc/tuples.link_unit.html index 839990e1587c6..37f19030aa1f6 100644 --- a/tests/rustdoc/tuples.link_unit.html +++ b/tests/rustdoc/tuples.link_unit.html @@ -1 +1 @@ -pub fn tuple0(x: ()) \ No newline at end of file +pub fn tuple0(x: ()) \ No newline at end of file