Skip to content

Commit dbad77f

Browse files
Remove thread-local for playground config
1 parent ade8b02 commit dbad77f

File tree

6 files changed

+147
-117
lines changed

6 files changed

+147
-117
lines changed

src/librustdoc/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ impl Options {
378378
&matches.opt_strs("html-after-content"),
379379
&matches.opt_strs("markdown-before-content"),
380380
&matches.opt_strs("markdown-after-content"),
381-
&diag, &mut id_map, edition) {
381+
&diag, &mut id_map, edition, &None) {
382382
Some(eh) => eh,
383383
None => return Err(3),
384384
};

src/librustdoc/externalfiles.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::str;
44
use errors;
55
use crate::syntax::feature_gate::UnstableFeatures;
66
use crate::syntax::edition::Edition;
7-
use crate::html::markdown::{IdMap, ErrorCodes, Markdown};
7+
use crate::html::markdown::{IdMap, ErrorCodes, Markdown, Playground};
88

99
use std::cell::RefCell;
1010

@@ -24,7 +24,7 @@ pub struct ExternalHtml {
2424
impl ExternalHtml {
2525
pub fn load(in_header: &[String], before_content: &[String], after_content: &[String],
2626
md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler,
27-
id_map: &mut IdMap, edition: Edition)
27+
id_map: &mut IdMap, edition: Edition, playground: &Option<Playground>)
2828
-> Option<ExternalHtml> {
2929
let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
3030
load_external_files(in_header, diag)
@@ -36,7 +36,7 @@ impl ExternalHtml {
3636
load_external_files(md_before_content, diag)
3737
.map(|m_bc| (ih,
3838
format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map),
39-
codes, edition))))
39+
codes, edition, playground))))
4040
)
4141
.and_then(|(ih, bc)|
4242
load_external_files(after_content, diag)
@@ -46,7 +46,7 @@ impl ExternalHtml {
4646
load_external_files(md_after_content, diag)
4747
.map(|m_ac| (ih, bc,
4848
format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map),
49-
codes, edition))))
49+
codes, edition, playground))))
5050
)
5151
.map(|(ih, bc, ac)|
5252
ExternalHtml {

src/librustdoc/html/markdown.rs

Lines changed: 110 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
//! let s = "My *markdown* _text_";
1818
//! let mut id_map = IdMap::new();
1919
//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map),
20-
//! ErrorCodes::Yes, Edition::Edition2015));
20+
//! ErrorCodes::Yes, Edition::Edition2015, None));
2121
//! // ... something using html
2222
//! ```
2323
@@ -59,16 +59,24 @@ pub struct Markdown<'a>(
5959
pub ErrorCodes,
6060
/// Default edition to use when parsing doctests (to add a `fn main`).
6161
pub Edition,
62+
pub &'a Option<Playground>,
6263
);
6364
/// A tuple struct like `Markdown` that renders the markdown with a table of contents.
6465
pub struct MarkdownWithToc<'a>(
6566
pub &'a str,
6667
pub RefCell<&'a mut IdMap>,
6768
pub ErrorCodes,
6869
pub Edition,
70+
pub &'a Option<Playground>,
6971
);
7072
/// A tuple struct like `Markdown` that renders the markdown escaping HTML tags.
71-
pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
73+
pub struct MarkdownHtml<'a>(
74+
pub &'a str,
75+
pub RefCell<&'a mut IdMap>,
76+
pub ErrorCodes,
77+
pub Edition,
78+
pub &'a Option<Playground>,
79+
);
7280
/// A tuple struct like `Markdown` that renders only the first paragraph.
7381
pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]);
7482

@@ -155,30 +163,39 @@ fn slugify(c: char) -> Option<char> {
155163
}
156164
}
157165

158-
// Information about the playground if a URL has been specified, containing an
159-
// optional crate name and the URL.
160-
thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> = {
161-
RefCell::new(None)
162-
});
166+
#[derive(Clone, Debug)]
167+
pub struct Playground {
168+
pub crate_name: Option<String>,
169+
pub url: String,
170+
}
163171

164172
/// Adds syntax highlighting and playground Run buttons to Rust code blocks.
165-
struct CodeBlocks<'a, I: Iterator<Item = Event<'a>>> {
173+
struct CodeBlocks<'p, 'a, I: Iterator<Item = Event<'a>>> {
166174
inner: I,
167175
check_error_codes: ErrorCodes,
168176
edition: Edition,
177+
// Information about the playground if a URL has been specified, containing an
178+
// optional crate name and the URL.
179+
playground: &'p Option<Playground>,
169180
}
170181

171-
impl<'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'a, I> {
172-
fn new(iter: I, error_codes: ErrorCodes, edition: Edition) -> Self {
182+
impl<'p, 'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'p, 'a, I> {
183+
fn new(
184+
iter: I,
185+
error_codes: ErrorCodes,
186+
edition: Edition,
187+
playground: &'p Option<Playground>,
188+
) -> Self {
173189
CodeBlocks {
174190
inner: iter,
175191
check_error_codes: error_codes,
176192
edition,
193+
playground,
177194
}
178195
}
179196
}
180197

181-
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
198+
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
182199
type Item = Event<'a>;
183200

184201
fn next(&mut self) -> Option<Self::Item> {
@@ -213,86 +230,86 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
213230
}
214231
let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
215232
let text = lines.collect::<Vec<Cow<'_, str>>>().join("\n");
216-
PLAYGROUND.with(|play| {
217-
// insert newline to clearly separate it from the
218-
// previous block so we can shorten the html output
219-
let mut s = String::from("\n");
220-
let playground_button = play.borrow().as_ref().and_then(|&(ref krate, ref url)| {
221-
if url.is_empty() {
222-
return None;
223-
}
224-
let test = origtext.lines()
225-
.map(|l| map_line(l).for_code())
226-
.collect::<Vec<Cow<'_, str>>>().join("\n");
227-
let krate = krate.as_ref().map(|s| &**s);
228-
let (test, _) = test::make_test(&test, krate, false,
229-
&Default::default(), edition);
230-
let channel = if test.contains("#![feature(") {
231-
"&amp;version=nightly"
232-
} else {
233-
""
234-
};
235-
236-
let edition_string = format!("&amp;edition={}", edition);
237-
238-
// These characters don't need to be escaped in a URI.
239-
// FIXME: use a library function for percent encoding.
240-
fn dont_escape(c: u8) -> bool {
241-
(b'a' <= c && c <= b'z') ||
242-
(b'A' <= c && c <= b'Z') ||
243-
(b'0' <= c && c <= b'9') ||
244-
c == b'-' || c == b'_' || c == b'.' ||
245-
c == b'~' || c == b'!' || c == b'\'' ||
246-
c == b'(' || c == b')' || c == b'*'
247-
}
248-
let mut test_escaped = String::new();
249-
for b in test.bytes() {
250-
if dont_escape(b) {
251-
test_escaped.push(char::from(b));
252-
} else {
253-
write!(test_escaped, "%{:02X}", b).unwrap();
254-
}
255-
}
256-
Some(format!(
257-
r#"<a class="test-arrow" target="_blank" href="{}?code={}{}{}">Run</a>"#,
258-
url, test_escaped, channel, edition_string
259-
))
260-
});
261-
262-
let tooltip = if ignore {
263-
Some(("This example is not tested".to_owned(), "ignore"))
264-
} else if compile_fail {
265-
Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
266-
} else if explicit_edition {
267-
Some((format!("This code runs with edition {}", edition), "edition"))
233+
// insert newline to clearly separate it from the
234+
// previous block so we can shorten the html output
235+
let mut s = String::from("\n");
236+
let playground_button = self.playground.as_ref().and_then(|playground| {
237+
let krate = &playground.crate_name;
238+
let url = &playground.url;
239+
if url.is_empty() {
240+
return None;
241+
}
242+
let test = origtext.lines()
243+
.map(|l| map_line(l).for_code())
244+
.collect::<Vec<Cow<'_, str>>>().join("\n");
245+
let krate = krate.as_ref().map(|s| &**s);
246+
let (test, _) = test::make_test(&test, krate, false,
247+
&Default::default(), edition);
248+
let channel = if test.contains("#![feature(") {
249+
"&amp;version=nightly"
268250
} else {
269-
None
251+
""
270252
};
271253

272-
if let Some((s1, s2)) = tooltip {
273-
s.push_str(&highlight::render_with_highlighting(
274-
&text,
275-
Some(&format!("rust-example-rendered{}",
276-
if ignore { " ignore" }
277-
else if compile_fail { " compile_fail" }
278-
else if explicit_edition { " edition " }
279-
else { "" })),
280-
playground_button.as_ref().map(String::as_str),
281-
Some((s1.as_str(), s2))));
282-
Some(Event::Html(s.into()))
283-
} else {
284-
s.push_str(&highlight::render_with_highlighting(
285-
&text,
286-
Some(&format!("rust-example-rendered{}",
287-
if ignore { " ignore" }
288-
else if compile_fail { " compile_fail" }
289-
else if explicit_edition { " edition " }
290-
else { "" })),
291-
playground_button.as_ref().map(String::as_str),
292-
None));
293-
Some(Event::Html(s.into()))
254+
let edition_string = format!("&amp;edition={}", edition);
255+
256+
// These characters don't need to be escaped in a URI.
257+
// FIXME: use a library function for percent encoding.
258+
fn dont_escape(c: u8) -> bool {
259+
(b'a' <= c && c <= b'z') ||
260+
(b'A' <= c && c <= b'Z') ||
261+
(b'0' <= c && c <= b'9') ||
262+
c == b'-' || c == b'_' || c == b'.' ||
263+
c == b'~' || c == b'!' || c == b'\'' ||
264+
c == b'(' || c == b')' || c == b'*'
294265
}
295-
})
266+
let mut test_escaped = String::new();
267+
for b in test.bytes() {
268+
if dont_escape(b) {
269+
test_escaped.push(char::from(b));
270+
} else {
271+
write!(test_escaped, "%{:02X}", b).unwrap();
272+
}
273+
}
274+
Some(format!(
275+
r#"<a class="test-arrow" target="_blank" href="{}?code={}{}{}">Run</a>"#,
276+
url, test_escaped, channel, edition_string
277+
))
278+
});
279+
280+
let tooltip = if ignore {
281+
Some(("This example is not tested".to_owned(), "ignore"))
282+
} else if compile_fail {
283+
Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
284+
} else if explicit_edition {
285+
Some((format!("This code runs with edition {}", edition), "edition"))
286+
} else {
287+
None
288+
};
289+
290+
if let Some((s1, s2)) = tooltip {
291+
s.push_str(&highlight::render_with_highlighting(
292+
&text,
293+
Some(&format!("rust-example-rendered{}",
294+
if ignore { " ignore" }
295+
else if compile_fail { " compile_fail" }
296+
else if explicit_edition { " edition " }
297+
else { "" })),
298+
playground_button.as_ref().map(String::as_str),
299+
Some((s1.as_str(), s2))));
300+
Some(Event::Html(s.into()))
301+
} else {
302+
s.push_str(&highlight::render_with_highlighting(
303+
&text,
304+
Some(&format!("rust-example-rendered{}",
305+
if ignore { " ignore" }
306+
else if compile_fail { " compile_fail" }
307+
else if explicit_edition { " edition " }
308+
else { "" })),
309+
playground_button.as_ref().map(String::as_str),
310+
None));
311+
Some(Event::Html(s.into()))
312+
}
296313
}
297314
}
298315

@@ -676,7 +693,7 @@ impl LangString {
676693

677694
impl<'a> fmt::Display for Markdown<'a> {
678695
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
679-
let Markdown(md, links, ref ids, codes, edition) = *self;
696+
let Markdown(md, links, ref ids, codes, edition, playground) = *self;
680697
let mut ids = ids.borrow_mut();
681698

682699
// This is actually common enough to special-case
@@ -695,7 +712,7 @@ impl<'a> fmt::Display for Markdown<'a> {
695712

696713
let p = HeadingLinks::new(p, None, &mut ids);
697714
let p = LinkReplacer::new(p, links);
698-
let p = CodeBlocks::new(p, codes, edition);
715+
let p = CodeBlocks::new(p, codes, edition, playground);
699716
let p = Footnotes::new(p);
700717
html::push_html(&mut s, p);
701718

@@ -705,7 +722,7 @@ impl<'a> fmt::Display for Markdown<'a> {
705722

706723
impl<'a> fmt::Display for MarkdownWithToc<'a> {
707724
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
708-
let MarkdownWithToc(md, ref ids, codes, edition) = *self;
725+
let MarkdownWithToc(md, ref ids, codes, edition, playground) = *self;
709726
let mut ids = ids.borrow_mut();
710727

711728
let p = Parser::new_ext(md, opts());
@@ -716,7 +733,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
716733

717734
{
718735
let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
719-
let p = CodeBlocks::new(p, codes, edition);
736+
let p = CodeBlocks::new(p, codes, edition, playground);
720737
let p = Footnotes::new(p);
721738
html::push_html(&mut s, p);
722739
}
@@ -729,7 +746,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
729746

730747
impl<'a> fmt::Display for MarkdownHtml<'a> {
731748
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
732-
let MarkdownHtml(md, ref ids, codes, edition) = *self;
749+
let MarkdownHtml(md, ref ids, codes, edition, playground) = *self;
733750
let mut ids = ids.borrow_mut();
734751

735752
// This is actually common enough to special-case
@@ -745,7 +762,7 @@ impl<'a> fmt::Display for MarkdownHtml<'a> {
745762
let mut s = String::with_capacity(md.len() * 3 / 2);
746763

747764
let p = HeadingLinks::new(p, None, &mut ids);
748-
let p = CodeBlocks::new(p, codes, edition);
765+
let p = CodeBlocks::new(p, codes, edition, playground);
749766
let p = Footnotes::new(p);
750767
html::push_html(&mut s, p);
751768

0 commit comments

Comments
 (0)