Skip to content

Commit 3254d61

Browse files
committed
Auto merge of rust-lang#136784 - yotamofek:pr/rustdoc-remove-buffer-take2, 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
2 parents 124cc92 + cbfbc2f commit 3254d61

13 files changed

+366
-363
lines changed

src/librustdoc/html/format.rs

+29-105
Original file line numberDiff line numberDiff line change
@@ -37,114 +37,36 @@ use crate::html::render::Context;
3737
use crate::joined::Joined as _;
3838
use crate::passes::collect_intra_doc_links::UrlFragment;
3939

40-
pub(crate) trait Print {
41-
fn print(self, buffer: &mut Buffer);
42-
}
43-
44-
impl<F> Print for F
45-
where
46-
F: FnOnce(&mut Buffer),
47-
{
48-
fn print(self, buffer: &mut Buffer) {
49-
(self)(buffer)
50-
}
51-
}
52-
53-
impl Print for String {
54-
fn print(self, buffer: &mut Buffer) {
55-
buffer.write_str(&self);
56-
}
57-
}
58-
59-
impl Print for &'_ str {
60-
fn print(self, buffer: &mut Buffer) {
61-
buffer.write_str(self);
62-
}
63-
}
40+
/// This macro is the same as [`std::write!`] for [`String`]s, but swallows the returned `Result`,
41+
/// since writing into a `String` can never fail.
42+
macro_rules! write_str {
43+
($dst:expr, $($arg:tt)*) => {{
44+
// make sure $dst is a `String` (or `&mut String`)
45+
trait AssertString {
46+
fn assert_string(&mut self) {}
47+
}
48+
impl AssertString for ::std::string::String {}
49+
$dst.assert_string();
6450

65-
#[derive(Debug, Clone)]
66-
pub(crate) struct Buffer {
67-
for_html: bool,
68-
buffer: String,
51+
let _ = $dst.write_fmt(::std::format_args!($($arg)*));
52+
}};
6953
}
54+
/// This macro is the same as [`std::writeln!`] for [`String`]s, but swallows the returned `Result`,
55+
/// since writing into a `String` can never fail.
56+
macro_rules! writeln_str {
57+
($dst:expr, $($arg:tt)*) => {{
58+
// make sure $dst is a `String` (or `&mut String`)
59+
trait AssertString {
60+
fn assert_string(&mut self) {}
61+
}
62+
impl AssertString for ::std::string::String {}
63+
$dst.assert_string();
7064

71-
impl core::fmt::Write for Buffer {
72-
#[inline]
73-
fn write_str(&mut self, s: &str) -> fmt::Result {
74-
self.buffer.write_str(s)
75-
}
76-
77-
#[inline]
78-
fn write_char(&mut self, c: char) -> fmt::Result {
79-
self.buffer.write_char(c)
80-
}
81-
82-
#[inline]
83-
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
84-
self.buffer.write_fmt(args)
85-
}
65+
let _ = $dst.write_fmt(::std::format_args_nl!($($arg)*));
66+
}};
8667
}
8768

88-
impl Buffer {
89-
pub(crate) fn empty_from(v: &Buffer) -> Buffer {
90-
Buffer { for_html: v.for_html, buffer: String::new() }
91-
}
92-
93-
pub(crate) fn html() -> Buffer {
94-
Buffer { for_html: true, buffer: String::new() }
95-
}
96-
97-
pub(crate) fn new() -> Buffer {
98-
Buffer { for_html: false, buffer: String::new() }
99-
}
100-
101-
pub(crate) fn is_empty(&self) -> bool {
102-
self.buffer.is_empty()
103-
}
104-
105-
pub(crate) fn into_inner(self) -> String {
106-
self.buffer
107-
}
108-
109-
pub(crate) fn push(&mut self, c: char) {
110-
self.buffer.push(c);
111-
}
112-
113-
pub(crate) fn push_str(&mut self, s: &str) {
114-
self.buffer.push_str(s);
115-
}
116-
117-
pub(crate) fn push_buffer(&mut self, other: Buffer) {
118-
self.buffer.push_str(&other.buffer);
119-
}
120-
121-
// Intended for consumption by write! and writeln! (std::fmt) but without
122-
// the fmt::Result return type imposed by fmt::Write (and avoiding the trait
123-
// import).
124-
pub(crate) fn write_str(&mut self, s: &str) {
125-
self.buffer.push_str(s);
126-
}
127-
128-
// Intended for consumption by write! and writeln! (std::fmt) but without
129-
// the fmt::Result return type imposed by fmt::Write (and avoiding the trait
130-
// import).
131-
pub(crate) fn write_fmt(&mut self, v: fmt::Arguments<'_>) {
132-
self.buffer.write_fmt(v).unwrap();
133-
}
134-
135-
pub(crate) fn to_display<T: Print>(mut self, t: T) -> String {
136-
t.print(&mut self);
137-
self.into_inner()
138-
}
139-
140-
pub(crate) fn reserve(&mut self, additional: usize) {
141-
self.buffer.reserve(additional)
142-
}
143-
144-
pub(crate) fn len(&self) -> usize {
145-
self.buffer.len()
146-
}
147-
}
69+
pub(crate) use {write_str, writeln_str};
14870

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

769691
pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Context<'_>) -> String {
692+
use write_str as write;
693+
770694
let cache = cx.cache();
771695
let Some((fqp, shortty)) = cache.paths.get(&did).or_else(|| cache.external_paths.get(&did))
772696
else {
773697
return String::new();
774698
};
775-
let mut buf = Buffer::new();
699+
let mut buf = String::new();
776700
let fqp = if *shortty == ItemType::Primitive {
777701
// primitives are documented in a crate, but not actually part of it
778702
&fqp[fqp.len() - 1..]
@@ -792,7 +716,7 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont
792716
write!(buf, "::{component}");
793717
}
794718
}
795-
buf.into_inner()
719+
buf
796720
}
797721

798722
/// Used to render a [`clean::Path`].

src/librustdoc/html/highlight.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_span::edition::Edition;
1414
use rustc_span::symbol::Symbol;
1515
use rustc_span::{BytePos, DUMMY_SP, Span};
1616

17-
use super::format::{self, Buffer};
17+
use super::format;
1818
use crate::clean::PrimitiveType;
1919
use crate::html::escape::EscapeBodyText;
2020
use crate::html::render::{Context, LinkFromSrc};
@@ -48,7 +48,7 @@ pub(crate) enum Tooltip {
4848
/// Highlights `src` as an inline example, returning the HTML output.
4949
pub(crate) fn render_example_with_highlighting(
5050
src: &str,
51-
out: &mut Buffer,
51+
out: &mut String,
5252
tooltip: Tooltip,
5353
playground_button: Option<&str>,
5454
extra_classes: &[String],
@@ -59,12 +59,14 @@ pub(crate) fn render_example_with_highlighting(
5959
}
6060

6161
fn write_header(
62-
out: &mut Buffer,
62+
out: &mut String,
6363
class: &str,
64-
extra_content: Option<Buffer>,
64+
extra_content: Option<&str>,
6565
tooltip: Tooltip,
6666
extra_classes: &[String],
6767
) {
68+
use super::format::write_str as write;
69+
6870
write!(
6971
out,
7072
"<div class=\"example-wrap{}\">",
@@ -96,7 +98,7 @@ fn write_header(
9698
}
9799

98100
if let Some(extra) = extra_content {
99-
out.push_buffer(extra);
101+
out.push_str(&extra);
100102
}
101103
if class.is_empty() {
102104
write!(
@@ -322,7 +324,8 @@ pub(super) fn write_code(
322324
});
323325
}
324326

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

src/librustdoc/html/highlight/tests.rs

+10-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use rustc_data_structures::fx::FxIndexMap;
33
use rustc_span::create_default_session_globals_then;
44

55
use super::{DecorationInfo, write_code};
6-
use crate::html::format::Buffer;
76

87
const STYLE: &str = r#"
98
<style>
@@ -22,9 +21,9 @@ fn test_html_highlighting() {
2221
create_default_session_globals_then(|| {
2322
let src = include_str!("fixtures/sample.rs");
2423
let html = {
25-
let mut out = Buffer::new();
24+
let mut out = String::new();
2625
write_code(&mut out, src, None, None);
27-
format!("{STYLE}<pre><code>{}</code></pre>\n", out.into_inner())
26+
format!("{STYLE}<pre><code>{out}</code></pre>\n")
2827
};
2928
expect_file!["fixtures/sample.html"].assert_eq(&html);
3029
});
@@ -36,9 +35,9 @@ fn test_dos_backline() {
3635
let src = "pub fn foo() {\r\n\
3736
println!(\"foo\");\r\n\
3837
}\r\n";
39-
let mut html = Buffer::new();
38+
let mut html = String::new();
4039
write_code(&mut html, src, None, None);
41-
expect_file!["fixtures/dos_line.html"].assert_eq(&html.into_inner());
40+
expect_file!["fixtures/dos_line.html"].assert_eq(&html);
4241
});
4342
}
4443

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

53-
let mut html = Buffer::new();
52+
let mut html = String::new();
5453
write_code(&mut html, src, None, None);
55-
expect_file!["fixtures/highlight.html"].assert_eq(&html.into_inner());
54+
expect_file!["fixtures/highlight.html"].assert_eq(&html);
5655
});
5756
}
5857

5958
#[test]
6059
fn test_union_highlighting() {
6160
create_default_session_globals_then(|| {
6261
let src = include_str!("fixtures/union.rs");
63-
let mut html = Buffer::new();
62+
let mut html = String::new();
6463
write_code(&mut html, src, None, None);
65-
expect_file!["fixtures/union.html"].assert_eq(&html.into_inner());
64+
expect_file!["fixtures/union.html"].assert_eq(&html);
6665
});
6766
}
6867

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

80-
let mut html = Buffer::new();
79+
let mut html = String::new();
8180
write_code(&mut html, src, None, Some(&DecorationInfo(decorations)));
82-
expect_file!["fixtures/decorations.html"].assert_eq(&html.into_inner());
81+
expect_file!["fixtures/decorations.html"].assert_eq(&html);
8382
});
8483
}

src/librustdoc/html/layout.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
use std::fmt::{self, Display};
12
use std::path::PathBuf;
23

34
use rinja::Template;
45
use rustc_data_structures::fx::FxIndexMap;
56

67
use super::static_files::{STATIC_FILES, StaticFiles};
78
use crate::externalfiles::ExternalHtml;
8-
use crate::html::format::{Buffer, Print};
99
use crate::html::render::{StylePath, ensure_trailing_slash};
1010

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

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

74-
pub(crate) fn render<T: Print, S: Print>(
74+
/// Implements [`Display`] for a function that accepts a mutable reference to a [`String`], and (optionally) writes to it.
75+
///
76+
/// The wrapped function will receive an empty string, and can modify it,
77+
/// and the `Display` implementation will write the contents of the string after the function has finished.
78+
pub(crate) struct BufDisplay<F>(pub F);
79+
80+
impl<F> Display for BufDisplay<F>
81+
where
82+
F: Fn(&mut String),
83+
{
84+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85+
let mut buf = String::new();
86+
self.0(&mut buf);
87+
f.write_str(&buf)
88+
}
89+
}
90+
91+
pub(crate) fn render<T: Display, S: Display>(
7592
layout: &Layout,
7693
page: &Page<'_>,
7794
sidebar: S,
@@ -98,8 +115,8 @@ pub(crate) fn render<T: Print, S: Print>(
98115
let mut themes: Vec<String> = style_files.iter().map(|s| s.basename().unwrap()).collect();
99116
themes.sort();
100117

101-
let content = Buffer::html().to_display(t); // Note: This must happen before making the sidebar.
102-
let sidebar = Buffer::html().to_display(sidebar);
118+
let content = t.to_string(); // Note: This must happen before making the sidebar.
119+
let sidebar = sidebar.to_string();
103120
PageLayout {
104121
static_root_path,
105122
page,

src/librustdoc/html/markdown.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ use crate::clean::RenderedLink;
5252
use crate::doctest;
5353
use crate::doctest::GlobalTestOptions;
5454
use crate::html::escape::{Escape, EscapeBodyText};
55-
use crate::html::format::Buffer;
5655
use crate::html::highlight;
5756
use crate::html::length_limit::HtmlWithLimit;
5857
use crate::html::render::small_url_encode;
@@ -329,7 +328,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
329328

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

335334
highlight::render_example_with_highlighting(
@@ -339,7 +338,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
339338
playground_button.as_deref(),
340339
&added_classes,
341340
);
342-
Some(Event::Html(s.into_inner().into()))
341+
Some(Event::Html(s.into()))
343342
}
344343
}
345344

0 commit comments

Comments
 (0)