Skip to content

Commit

Permalink
Auto merge of rust-lang#136784 - yotamofek:pr/rustdoc-remove-buffer-t…
Browse files Browse the repository at this point in the history
…ake2, r=<try>

Nuke `Buffer` abstraction from `librustdoc`, take 2 💣

In rust-lang#136656 I found out that the for_html field in the Buffer struct was never read, and pondered if Buffer had any utility at all. `@GuillaumeGomez` said he agrees that it can be just removed. So this PR is me removing it. So, r? `@aDotInTheVoid` , maybe?

Supersedes rust-lang#136748
  • Loading branch information
bors committed Feb 9, 2025
2 parents 124cc92 + cbfbc2f commit 3254d61
Show file tree
Hide file tree
Showing 13 changed files with 366 additions and 363 deletions.
134 changes: 29 additions & 105 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,114 +37,36 @@ use crate::html::render::Context;
use crate::joined::Joined as _;
use crate::passes::collect_intra_doc_links::UrlFragment;

pub(crate) trait Print {
fn print(self, buffer: &mut Buffer);
}

impl<F> Print for F
where
F: FnOnce(&mut Buffer),
{
fn print(self, buffer: &mut Buffer) {
(self)(buffer)
}
}

impl Print for String {
fn print(self, buffer: &mut Buffer) {
buffer.write_str(&self);
}
}

impl Print for &'_ str {
fn print(self, buffer: &mut Buffer) {
buffer.write_str(self);
}
}
/// This macro is the same as [`std::write!`] for [`String`]s, but swallows the returned `Result`,
/// since writing into a `String` can never fail.
macro_rules! write_str {
($dst:expr, $($arg:tt)*) => {{
// make sure $dst is a `String` (or `&mut String`)
trait AssertString {
fn assert_string(&mut self) {}
}
impl AssertString for ::std::string::String {}
$dst.assert_string();

#[derive(Debug, Clone)]
pub(crate) struct Buffer {
for_html: bool,
buffer: String,
let _ = $dst.write_fmt(::std::format_args!($($arg)*));
}};
}
/// This macro is the same as [`std::writeln!`] for [`String`]s, but swallows the returned `Result`,
/// since writing into a `String` can never fail.
macro_rules! writeln_str {
($dst:expr, $($arg:tt)*) => {{
// make sure $dst is a `String` (or `&mut String`)
trait AssertString {
fn assert_string(&mut self) {}
}
impl AssertString for ::std::string::String {}
$dst.assert_string();

impl core::fmt::Write for Buffer {
#[inline]
fn write_str(&mut self, s: &str) -> fmt::Result {
self.buffer.write_str(s)
}

#[inline]
fn write_char(&mut self, c: char) -> fmt::Result {
self.buffer.write_char(c)
}

#[inline]
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
self.buffer.write_fmt(args)
}
let _ = $dst.write_fmt(::std::format_args_nl!($($arg)*));
}};
}

impl Buffer {
pub(crate) fn empty_from(v: &Buffer) -> Buffer {
Buffer { for_html: v.for_html, buffer: String::new() }
}

pub(crate) fn html() -> Buffer {
Buffer { for_html: true, buffer: String::new() }
}

pub(crate) fn new() -> Buffer {
Buffer { for_html: false, buffer: String::new() }
}

pub(crate) fn is_empty(&self) -> bool {
self.buffer.is_empty()
}

pub(crate) fn into_inner(self) -> String {
self.buffer
}

pub(crate) fn push(&mut self, c: char) {
self.buffer.push(c);
}

pub(crate) fn push_str(&mut self, s: &str) {
self.buffer.push_str(s);
}

pub(crate) fn push_buffer(&mut self, other: Buffer) {
self.buffer.push_str(&other.buffer);
}

// Intended for consumption by write! and writeln! (std::fmt) but without
// the fmt::Result return type imposed by fmt::Write (and avoiding the trait
// import).
pub(crate) fn write_str(&mut self, s: &str) {
self.buffer.push_str(s);
}

// Intended for consumption by write! and writeln! (std::fmt) but without
// the fmt::Result return type imposed by fmt::Write (and avoiding the trait
// import).
pub(crate) fn write_fmt(&mut self, v: fmt::Arguments<'_>) {
self.buffer.write_fmt(v).unwrap();
}

pub(crate) fn to_display<T: Print>(mut self, t: T) -> String {
t.print(&mut self);
self.into_inner()
}

pub(crate) fn reserve(&mut self, additional: usize) {
self.buffer.reserve(additional)
}

pub(crate) fn len(&self) -> usize {
self.buffer.len()
}
}
pub(crate) use {write_str, writeln_str};

pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
bounds: &'a [clean::GenericBound],
Expand Down Expand Up @@ -767,12 +689,14 @@ pub(crate) fn href_relative_parts<'fqp>(
}

pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Context<'_>) -> String {
use write_str as write;

let cache = cx.cache();
let Some((fqp, shortty)) = cache.paths.get(&did).or_else(|| cache.external_paths.get(&did))
else {
return String::new();
};
let mut buf = Buffer::new();
let mut buf = String::new();
let fqp = if *shortty == ItemType::Primitive {
// primitives are documented in a crate, but not actually part of it
&fqp[fqp.len() - 1..]
Expand All @@ -792,7 +716,7 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont
write!(buf, "::{component}");
}
}
buf.into_inner()
buf
}

/// Used to render a [`clean::Path`].
Expand Down
15 changes: 9 additions & 6 deletions src/librustdoc/html/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_span::edition::Edition;
use rustc_span::symbol::Symbol;
use rustc_span::{BytePos, DUMMY_SP, Span};

use super::format::{self, Buffer};
use super::format;
use crate::clean::PrimitiveType;
use crate::html::escape::EscapeBodyText;
use crate::html::render::{Context, LinkFromSrc};
Expand Down Expand Up @@ -48,7 +48,7 @@ pub(crate) enum Tooltip {
/// Highlights `src` as an inline example, returning the HTML output.
pub(crate) fn render_example_with_highlighting(
src: &str,
out: &mut Buffer,
out: &mut String,
tooltip: Tooltip,
playground_button: Option<&str>,
extra_classes: &[String],
Expand All @@ -59,12 +59,14 @@ pub(crate) fn render_example_with_highlighting(
}

fn write_header(
out: &mut Buffer,
out: &mut String,
class: &str,
extra_content: Option<Buffer>,
extra_content: Option<&str>,
tooltip: Tooltip,
extra_classes: &[String],
) {
use super::format::write_str as write;

write!(
out,
"<div class=\"example-wrap{}\">",
Expand Down Expand Up @@ -96,7 +98,7 @@ fn write_header(
}

if let Some(extra) = extra_content {
out.push_buffer(extra);
out.push_str(&extra);
}
if class.is_empty() {
write!(
Expand Down Expand Up @@ -322,7 +324,8 @@ pub(super) fn write_code(
});
}

fn write_footer(out: &mut Buffer, playground_button: Option<&str>) {
fn write_footer(out: &mut String, playground_button: Option<&str>) {
use super::format::writeln_str as writeln;
writeln!(out, "</code></pre>{}</div>", playground_button.unwrap_or_default());
}

Expand Down
21 changes: 10 additions & 11 deletions src/librustdoc/html/highlight/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxIndexMap;
use rustc_span::create_default_session_globals_then;

use super::{DecorationInfo, write_code};
use crate::html::format::Buffer;

const STYLE: &str = r#"
<style>
Expand All @@ -22,9 +21,9 @@ fn test_html_highlighting() {
create_default_session_globals_then(|| {
let src = include_str!("fixtures/sample.rs");
let html = {
let mut out = Buffer::new();
let mut out = String::new();
write_code(&mut out, src, None, None);
format!("{STYLE}<pre><code>{}</code></pre>\n", out.into_inner())
format!("{STYLE}<pre><code>{out}</code></pre>\n")
};
expect_file!["fixtures/sample.html"].assert_eq(&html);
});
Expand All @@ -36,9 +35,9 @@ fn test_dos_backline() {
let src = "pub fn foo() {\r\n\
println!(\"foo\");\r\n\
}\r\n";
let mut html = Buffer::new();
let mut html = String::new();
write_code(&mut html, src, None, None);
expect_file!["fixtures/dos_line.html"].assert_eq(&html.into_inner());
expect_file!["fixtures/dos_line.html"].assert_eq(&html);
});
}

Expand All @@ -50,19 +49,19 @@ use self::whatever;
let x = super::b::foo;
let y = Self::whatever;";

let mut html = Buffer::new();
let mut html = String::new();
write_code(&mut html, src, None, None);
expect_file!["fixtures/highlight.html"].assert_eq(&html.into_inner());
expect_file!["fixtures/highlight.html"].assert_eq(&html);
});
}

#[test]
fn test_union_highlighting() {
create_default_session_globals_then(|| {
let src = include_str!("fixtures/union.rs");
let mut html = Buffer::new();
let mut html = String::new();
write_code(&mut html, src, None, None);
expect_file!["fixtures/union.html"].assert_eq(&html.into_inner());
expect_file!["fixtures/union.html"].assert_eq(&html);
});
}

Expand All @@ -77,8 +76,8 @@ let a = 4;";
decorations.insert("example", vec![(0, 10), (11, 21)]);
decorations.insert("example2", vec![(22, 32)]);

let mut html = Buffer::new();
let mut html = String::new();
write_code(&mut html, src, None, Some(&DecorationInfo(decorations)));
expect_file!["fixtures/decorations.html"].assert_eq(&html.into_inner());
expect_file!["fixtures/decorations.html"].assert_eq(&html);
});
}
25 changes: 21 additions & 4 deletions src/librustdoc/html/layout.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::fmt::{self, Display};
use std::path::PathBuf;

use rinja::Template;
use rustc_data_structures::fx::FxIndexMap;

use super::static_files::{STATIC_FILES, StaticFiles};
use crate::externalfiles::ExternalHtml;
use crate::html::format::{Buffer, Print};
use crate::html::render::{StylePath, ensure_trailing_slash};

#[derive(Clone)]
Expand Down Expand Up @@ -71,7 +71,24 @@ struct PageLayout<'a> {

pub(crate) use crate::html::render::sidebar::filters;

pub(crate) fn render<T: Print, S: Print>(
/// Implements [`Display`] for a function that accepts a mutable reference to a [`String`], and (optionally) writes to it.
///
/// The wrapped function will receive an empty string, and can modify it,
/// and the `Display` implementation will write the contents of the string after the function has finished.
pub(crate) struct BufDisplay<F>(pub F);

impl<F> Display for BufDisplay<F>
where
F: Fn(&mut String),
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut buf = String::new();
self.0(&mut buf);
f.write_str(&buf)
}
}

pub(crate) fn render<T: Display, S: Display>(
layout: &Layout,
page: &Page<'_>,
sidebar: S,
Expand All @@ -98,8 +115,8 @@ pub(crate) fn render<T: Print, S: Print>(
let mut themes: Vec<String> = style_files.iter().map(|s| s.basename().unwrap()).collect();
themes.sort();

let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar.
let sidebar = Buffer::html().to_display(sidebar);
let content = t.to_string(); // Note: This must happen before making the sidebar.
let sidebar = sidebar.to_string();
PageLayout {
static_root_path,
page,
Expand Down
5 changes: 2 additions & 3 deletions src/librustdoc/html/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ use crate::clean::RenderedLink;
use crate::doctest;
use crate::doctest::GlobalTestOptions;
use crate::html::escape::{Escape, EscapeBodyText};
use crate::html::format::Buffer;
use crate::html::highlight;
use crate::html::length_limit::HtmlWithLimit;
use crate::html::render::small_url_encode;
Expand Down Expand Up @@ -329,7 +328,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {

// insert newline to clearly separate it from the
// previous block so we can shorten the html output
let mut s = Buffer::new();
let mut s = String::new();
s.push('\n');

highlight::render_example_with_highlighting(
Expand All @@ -339,7 +338,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
playground_button.as_deref(),
&added_classes,
);
Some(Event::Html(s.into_inner().into()))
Some(Event::Html(s.into()))
}
}

Expand Down
Loading

0 comments on commit 3254d61

Please sign in to comment.