Skip to content

Commit 231fbd4

Browse files
committed
wip
1 parent d2f335d commit 231fbd4

File tree

12 files changed

+2875
-2806
lines changed

12 files changed

+2875
-2806
lines changed

src/librustdoc/html/format.rs

+54-164
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//! some of them support an alternate format that emits text, but that should
88
//! not be used external to this module.
99
10-
use std::borrow::Cow;
1110
use std::cmp::Ordering;
1211
use std::fmt::{self, Display, Write};
1312
use std::iter::{self, once};
@@ -37,115 +36,6 @@ use crate::html::render::Context;
3736
use crate::joined::Joined as _;
3837
use crate::passes::collect_intra_doc_links::UrlFragment;
3938

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-
}
64-
65-
#[derive(Debug, Clone)]
66-
pub(crate) struct Buffer {
67-
for_html: bool,
68-
buffer: String,
69-
}
70-
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-
}
86-
}
87-
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-
}
148-
14939
pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
15040
bounds: &'a [clean::GenericBound],
15141
cx: &'a Context<'tcx>,
@@ -772,27 +662,29 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont
772662
else {
773663
return String::new();
774664
};
775-
let mut buf = Buffer::new();
776665
let fqp = if *shortty == ItemType::Primitive {
777666
// primitives are documented in a crate, but not actually part of it
778667
&fqp[fqp.len() - 1..]
779668
} else {
780669
fqp
781670
};
782-
if let &Some(UrlFragment::Item(id)) = fragment {
783-
write!(buf, "{} ", cx.tcx().def_descr(id));
784-
for component in fqp {
785-
write!(buf, "{component}::");
786-
}
787-
write!(buf, "{}", cx.tcx().item_name(id));
788-
} else if !fqp.is_empty() {
789-
let mut fqp_it = fqp.iter();
790-
write!(buf, "{shortty} {}", fqp_it.next().unwrap());
791-
for component in fqp_it {
792-
write!(buf, "::{component}");
671+
fmt::from_fn(|f| {
672+
if let &Some(UrlFragment::Item(id)) = fragment {
673+
write!(f, "{} ", cx.tcx().def_descr(id))?;
674+
for component in fqp {
675+
write!(f, "{component}::")?;
676+
}
677+
write!(f, "{}", cx.tcx().item_name(id))?;
678+
} else if !fqp.is_empty() {
679+
let mut fqp_it = fqp.iter();
680+
write!(f, "{shortty} {}", fqp_it.next().unwrap())?;
681+
for component in fqp_it {
682+
write!(f, "::{component}")?;
683+
}
793684
}
794-
}
795-
buf.into_inner()
685+
Ok(())
686+
})
687+
.to_string()
796688
}
797689

798690
/// Used to render a [`clean::Path`].
@@ -954,7 +846,7 @@ pub(crate) fn anchor<'a: 'cx, 'cx>(
954846
text = EscapeBodyText(text.as_str()),
955847
)
956848
} else {
957-
f.write_str(text.as_str())
849+
write!(f, "{text}")
958850
}
959851
})
960852
}
@@ -1533,53 +1425,51 @@ impl clean::FnDecl {
15331425
}
15341426

15351427
pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
1536-
item: &clean::Item,
1428+
item: &'a clean::Item,
15371429
cx: &'a Context<'tcx>,
15381430
) -> impl Display + 'a + Captures<'tcx> {
1539-
use std::fmt::Write as _;
1540-
let vis: Cow<'static, str> = match item.visibility(cx.tcx()) {
1541-
None => "".into(),
1542-
Some(ty::Visibility::Public) => "pub ".into(),
1543-
Some(ty::Visibility::Restricted(vis_did)) => {
1544-
// FIXME(camelid): This may not work correctly if `item_did` is a module.
1545-
// However, rustdoc currently never displays a module's
1546-
// visibility, so it shouldn't matter.
1547-
let parent_module = find_nearest_parent_module(cx.tcx(), item.item_id.expect_def_id());
1548-
1549-
if vis_did.is_crate_root() {
1550-
"pub(crate) ".into()
1551-
} else if parent_module == Some(vis_did) {
1552-
// `pub(in foo)` where `foo` is the parent module
1553-
// is the same as no visibility modifier
1554-
"".into()
1555-
} else if parent_module.and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
1556-
== Some(vis_did)
1557-
{
1558-
"pub(super) ".into()
1559-
} else {
1560-
let path = cx.tcx().def_path(vis_did);
1561-
debug!("path={path:?}");
1562-
// modified from `resolved_path()` to work with `DefPathData`
1563-
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
1564-
let anchor = anchor(vis_did, last_name, cx);
1565-
1566-
let mut s = "pub(in ".to_owned();
1567-
for seg in &path.data[..path.data.len() - 1] {
1568-
let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap());
1569-
}
1570-
let _ = write!(s, "{anchor}) ");
1571-
s.into()
1572-
}
1573-
}
1574-
};
1575-
15761431
let is_doc_hidden = item.is_doc_hidden();
15771432
fmt::from_fn(move |f| {
15781433
if is_doc_hidden {
15791434
f.write_str("#[doc(hidden)] ")?;
15801435
}
15811436

1582-
f.write_str(&vis)
1437+
match item.visibility(cx.tcx()) {
1438+
None => Ok(()),
1439+
Some(ty::Visibility::Public) => f.write_str("pub "),
1440+
Some(ty::Visibility::Restricted(vis_did)) => {
1441+
// FIXME(camelid): This may not work correctly if `item_did` is a module.
1442+
// However, rustdoc currently never displays a module's
1443+
// visibility, so it shouldn't matter.
1444+
let parent_module =
1445+
find_nearest_parent_module(cx.tcx(), item.item_id.expect_def_id());
1446+
1447+
if vis_did.is_crate_root() {
1448+
f.write_str("pub(crate) ")
1449+
} else if parent_module == Some(vis_did) {
1450+
// `pub(in foo)` where `foo` is the parent module
1451+
// is the same as no visibility modifier
1452+
Ok(())
1453+
} else if parent_module
1454+
.and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
1455+
== Some(vis_did)
1456+
{
1457+
f.write_str("pub(super) ")
1458+
} else {
1459+
let path = cx.tcx().def_path(vis_did);
1460+
debug!("path={path:?}");
1461+
// modified from `resolved_path()` to work with `DefPathData`
1462+
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
1463+
let anchor = anchor(vis_did, last_name, cx);
1464+
1465+
f.write_str("pub(in ")?;
1466+
for seg in &path.data[..path.data.len() - 1] {
1467+
write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
1468+
}
1469+
write!(f, "{anchor}) ")
1470+
}
1471+
}
1472+
}
15831473
})
15841474
}
15851475

0 commit comments

Comments
 (0)