about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2019-08-10 18:07:07 -0400
committerMark Rousskov <mark.simulacrum@gmail.com>2019-08-11 10:36:46 -0400
commitdbad77ffdd59e54b3f496cfbdb7909a6bbd03031 (patch)
tree4c3e555d63d45547abb221ceca33ba345586bbd5 /src
parentade8b02828de9653e6aca122f1a0f6d8c48ad29b (diff)
downloadrust-dbad77ffdd59e54b3f496cfbdb7909a6bbd03031.tar.gz
rust-dbad77ffdd59e54b3f496cfbdb7909a6bbd03031.zip
Remove thread-local for playground config
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/config.rs2
-rw-r--r--src/librustdoc/externalfiles.rs8
-rw-r--r--src/librustdoc/html/markdown.rs203
-rw-r--r--src/librustdoc/html/render.rs29
-rw-r--r--src/librustdoc/markdown.rs11
-rw-r--r--src/tools/error_index_generator/main.rs11
6 files changed, 147 insertions, 117 deletions
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 2be67d707fe..98ab957ecbb 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -378,7 +378,7 @@ impl Options {
                 &matches.opt_strs("html-after-content"),
                 &matches.opt_strs("markdown-before-content"),
                 &matches.opt_strs("markdown-after-content"),
-                &diag, &mut id_map, edition) {
+                &diag, &mut id_map, edition, &None) {
             Some(eh) => eh,
             None => return Err(3),
         };
diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index d604ba11d41..d920b7c4c91 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -4,7 +4,7 @@ use std::str;
 use errors;
 use crate::syntax::feature_gate::UnstableFeatures;
 use crate::syntax::edition::Edition;
-use crate::html::markdown::{IdMap, ErrorCodes, Markdown};
+use crate::html::markdown::{IdMap, ErrorCodes, Markdown, Playground};
 
 use std::cell::RefCell;
 
@@ -24,7 +24,7 @@ pub struct ExternalHtml {
 impl ExternalHtml {
     pub fn load(in_header: &[String], before_content: &[String], after_content: &[String],
                 md_before_content: &[String], md_after_content: &[String], diag: &errors::Handler,
-                id_map: &mut IdMap, edition: Edition)
+                id_map: &mut IdMap, edition: Edition, playground: &Option<Playground>)
             -> Option<ExternalHtml> {
         let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
         load_external_files(in_header, diag)
@@ -36,7 +36,7 @@ impl ExternalHtml {
                 load_external_files(md_before_content, diag)
                     .map(|m_bc| (ih,
                             format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map),
-                                    codes, edition))))
+                                    codes, edition, playground))))
             )
             .and_then(|(ih, bc)|
                 load_external_files(after_content, diag)
@@ -46,7 +46,7 @@ impl ExternalHtml {
                 load_external_files(md_after_content, diag)
                     .map(|m_ac| (ih, bc,
                             format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map),
-                                    codes, edition))))
+                                    codes, edition, playground))))
             )
             .map(|(ih, bc, ac)|
                 ExternalHtml {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index ef52ce62875..73233a2289c 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -17,7 +17,7 @@
 //! let s = "My *markdown* _text_";
 //! let mut id_map = IdMap::new();
 //! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map),
-//!                                   ErrorCodes::Yes, Edition::Edition2015));
+//!                                   ErrorCodes::Yes, Edition::Edition2015, None));
 //! // ... something using html
 //! ```
 
@@ -59,6 +59,7 @@ pub struct Markdown<'a>(
     pub ErrorCodes,
     /// Default edition to use when parsing doctests (to add a `fn main`).
     pub Edition,
+    pub &'a Option<Playground>,
 );
 /// A tuple struct like `Markdown` that renders the markdown with a table of contents.
 pub struct MarkdownWithToc<'a>(
@@ -66,9 +67,16 @@ pub struct MarkdownWithToc<'a>(
     pub RefCell<&'a mut IdMap>,
     pub ErrorCodes,
     pub Edition,
+    pub &'a Option<Playground>,
 );
 /// A tuple struct like `Markdown` that renders the markdown escaping HTML tags.
-pub struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
+pub struct MarkdownHtml<'a>(
+    pub &'a str,
+    pub RefCell<&'a mut IdMap>,
+    pub ErrorCodes,
+    pub Edition,
+    pub &'a Option<Playground>,
+);
 /// A tuple struct like `Markdown` that renders only the first paragraph.
 pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]);
 
@@ -155,30 +163,39 @@ fn slugify(c: char) -> Option<char> {
     }
 }
 
-// Information about the playground if a URL has been specified, containing an
-// optional crate name and the URL.
-thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> = {
-    RefCell::new(None)
-});
+#[derive(Clone, Debug)]
+pub struct Playground {
+    pub crate_name: Option<String>,
+    pub url: String,
+}
 
 /// Adds syntax highlighting and playground Run buttons to Rust code blocks.
-struct CodeBlocks<'a, I: Iterator<Item = Event<'a>>> {
+struct CodeBlocks<'p, 'a, I: Iterator<Item = Event<'a>>> {
     inner: I,
     check_error_codes: ErrorCodes,
     edition: Edition,
+    // Information about the playground if a URL has been specified, containing an
+    // optional crate name and the URL.
+    playground: &'p Option<Playground>,
 }
 
-impl<'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'a, I> {
-    fn new(iter: I, error_codes: ErrorCodes, edition: Edition) -> Self {
+impl<'p, 'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'p, 'a, I> {
+    fn new(
+        iter: I,
+        error_codes: ErrorCodes,
+        edition: Edition,
+        playground: &'p Option<Playground>,
+    ) -> Self {
         CodeBlocks {
             inner: iter,
             check_error_codes: error_codes,
             edition,
+            playground,
         }
     }
 }
 
-impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
+impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
     type Item = Event<'a>;
 
     fn next(&mut self) -> Option<Self::Item> {
@@ -213,86 +230,86 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
         }
         let lines = origtext.lines().filter_map(|l| map_line(l).for_html());
         let text = lines.collect::<Vec<Cow<'_, str>>>().join("\n");
-        PLAYGROUND.with(|play| {
-            // insert newline to clearly separate it from the
-            // previous block so we can shorten the html output
-            let mut s = String::from("\n");
-            let playground_button = play.borrow().as_ref().and_then(|&(ref krate, ref url)| {
-                if url.is_empty() {
-                    return None;
-                }
-                let test = origtext.lines()
-                    .map(|l| map_line(l).for_code())
-                    .collect::<Vec<Cow<'_, str>>>().join("\n");
-                let krate = krate.as_ref().map(|s| &**s);
-                let (test, _) = test::make_test(&test, krate, false,
-                                           &Default::default(), edition);
-                let channel = if test.contains("#![feature(") {
-                    "&amp;version=nightly"
-                } else {
-                    ""
-                };
-
-                let edition_string = format!("&amp;edition={}", edition);
-
-                // These characters don't need to be escaped in a URI.
-                // FIXME: use a library function for percent encoding.
-                fn dont_escape(c: u8) -> bool {
-                    (b'a' <= c && c <= b'z') ||
-                    (b'A' <= c && c <= b'Z') ||
-                    (b'0' <= c && c <= b'9') ||
-                    c == b'-' || c == b'_' || c == b'.' ||
-                    c == b'~' || c == b'!' || c == b'\'' ||
-                    c == b'(' || c == b')' || c == b'*'
-                }
-                let mut test_escaped = String::new();
-                for b in test.bytes() {
-                    if dont_escape(b) {
-                        test_escaped.push(char::from(b));
-                    } else {
-                        write!(test_escaped, "%{:02X}", b).unwrap();
-                    }
-                }
-                Some(format!(
-                    r#"<a class="test-arrow" target="_blank" href="{}?code={}{}{}">Run</a>"#,
-                    url, test_escaped, channel, edition_string
-                ))
-            });
-
-            let tooltip = if ignore {
-                Some(("This example is not tested".to_owned(), "ignore"))
-            } else if compile_fail {
-                Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
-            } else if explicit_edition {
-                Some((format!("This code runs with edition {}", edition), "edition"))
+        // insert newline to clearly separate it from the
+        // previous block so we can shorten the html output
+        let mut s = String::from("\n");
+        let playground_button = self.playground.as_ref().and_then(|playground| {
+            let krate = &playground.crate_name;
+            let url = &playground.url;
+            if url.is_empty() {
+                return None;
+            }
+            let test = origtext.lines()
+                .map(|l| map_line(l).for_code())
+                .collect::<Vec<Cow<'_, str>>>().join("\n");
+            let krate = krate.as_ref().map(|s| &**s);
+            let (test, _) = test::make_test(&test, krate, false,
+                                        &Default::default(), edition);
+            let channel = if test.contains("#![feature(") {
+                "&amp;version=nightly"
             } else {
-                None
+                ""
             };
 
-            if let Some((s1, s2)) = tooltip {
-                s.push_str(&highlight::render_with_highlighting(
-                    &text,
-                    Some(&format!("rust-example-rendered{}",
-                                  if ignore { " ignore" }
-                                  else if compile_fail { " compile_fail" }
-                                  else if explicit_edition { " edition " }
-                                  else { "" })),
-                    playground_button.as_ref().map(String::as_str),
-                    Some((s1.as_str(), s2))));
-                Some(Event::Html(s.into()))
-            } else {
-                s.push_str(&highlight::render_with_highlighting(
-                    &text,
-                    Some(&format!("rust-example-rendered{}",
-                                  if ignore { " ignore" }
-                                  else if compile_fail { " compile_fail" }
-                                  else if explicit_edition { " edition " }
-                                  else { "" })),
-                    playground_button.as_ref().map(String::as_str),
-                    None));
-                Some(Event::Html(s.into()))
+            let edition_string = format!("&amp;edition={}", edition);
+
+            // These characters don't need to be escaped in a URI.
+            // FIXME: use a library function for percent encoding.
+            fn dont_escape(c: u8) -> bool {
+                (b'a' <= c && c <= b'z') ||
+                (b'A' <= c && c <= b'Z') ||
+                (b'0' <= c && c <= b'9') ||
+                c == b'-' || c == b'_' || c == b'.' ||
+                c == b'~' || c == b'!' || c == b'\'' ||
+                c == b'(' || c == b')' || c == b'*'
             }
-        })
+            let mut test_escaped = String::new();
+            for b in test.bytes() {
+                if dont_escape(b) {
+                    test_escaped.push(char::from(b));
+                } else {
+                    write!(test_escaped, "%{:02X}", b).unwrap();
+                }
+            }
+            Some(format!(
+                r#"<a class="test-arrow" target="_blank" href="{}?code={}{}{}">Run</a>"#,
+                url, test_escaped, channel, edition_string
+            ))
+        });
+
+        let tooltip = if ignore {
+            Some(("This example is not tested".to_owned(), "ignore"))
+        } else if compile_fail {
+            Some(("This example deliberately fails to compile".to_owned(), "compile_fail"))
+        } else if explicit_edition {
+            Some((format!("This code runs with edition {}", edition), "edition"))
+        } else {
+            None
+        };
+
+        if let Some((s1, s2)) = tooltip {
+            s.push_str(&highlight::render_with_highlighting(
+                &text,
+                Some(&format!("rust-example-rendered{}",
+                                if ignore { " ignore" }
+                                else if compile_fail { " compile_fail" }
+                                else if explicit_edition { " edition " }
+                                else { "" })),
+                playground_button.as_ref().map(String::as_str),
+                Some((s1.as_str(), s2))));
+            Some(Event::Html(s.into()))
+        } else {
+            s.push_str(&highlight::render_with_highlighting(
+                &text,
+                Some(&format!("rust-example-rendered{}",
+                                if ignore { " ignore" }
+                                else if compile_fail { " compile_fail" }
+                                else if explicit_edition { " edition " }
+                                else { "" })),
+                playground_button.as_ref().map(String::as_str),
+                None));
+            Some(Event::Html(s.into()))
+        }
     }
 }
 
@@ -676,7 +693,7 @@ impl LangString {
 
 impl<'a> fmt::Display for Markdown<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let Markdown(md, links, ref ids, codes, edition) = *self;
+        let Markdown(md, links, ref ids, codes, edition, playground) = *self;
         let mut ids = ids.borrow_mut();
 
         // This is actually common enough to special-case
@@ -695,7 +712,7 @@ impl<'a> fmt::Display for Markdown<'a> {
 
         let p = HeadingLinks::new(p, None, &mut ids);
         let p = LinkReplacer::new(p, links);
-        let p = CodeBlocks::new(p, codes, edition);
+        let p = CodeBlocks::new(p, codes, edition, playground);
         let p = Footnotes::new(p);
         html::push_html(&mut s, p);
 
@@ -705,7 +722,7 @@ impl<'a> fmt::Display for Markdown<'a> {
 
 impl<'a> fmt::Display for MarkdownWithToc<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let MarkdownWithToc(md, ref ids, codes, edition) = *self;
+        let MarkdownWithToc(md, ref ids, codes, edition, playground) = *self;
         let mut ids = ids.borrow_mut();
 
         let p = Parser::new_ext(md, opts());
@@ -716,7 +733,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
 
         {
             let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
-            let p = CodeBlocks::new(p, codes, edition);
+            let p = CodeBlocks::new(p, codes, edition, playground);
             let p = Footnotes::new(p);
             html::push_html(&mut s, p);
         }
@@ -729,7 +746,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
 
 impl<'a> fmt::Display for MarkdownHtml<'a> {
     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
-        let MarkdownHtml(md, ref ids, codes, edition) = *self;
+        let MarkdownHtml(md, ref ids, codes, edition, playground) = *self;
         let mut ids = ids.borrow_mut();
 
         // This is actually common enough to special-case
@@ -745,7 +762,7 @@ impl<'a> fmt::Display for MarkdownHtml<'a> {
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
         let p = HeadingLinks::new(p, None, &mut ids);
-        let p = CodeBlocks::new(p, codes, edition);
+        let p = CodeBlocks::new(p, codes, edition, playground);
         let p = Footnotes::new(p);
         html::push_html(&mut s, p);
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index eb88c72da9e..8a7dfebdbbc 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -170,6 +170,7 @@ struct Context {
     /// The map used to ensure all generated 'id=' attributes are unique.
     id_map: Rc<RefCell<IdMap>>,
     pub shared: Arc<SharedContext>,
+    playground: Option<markdown::Playground>,
 }
 
 struct SharedContext {
@@ -574,9 +575,11 @@ pub fn run(mut krate: clean::Crate,
     };
 
     // If user passed in `--playground-url` arg, we fill in crate name here
+    let mut playground = None;
     if let Some(url) = playground_url {
-        markdown::PLAYGROUND.with(|slot| {
-            *slot.borrow_mut() = Some((Some(krate.name.clone()), url));
+        playground = Some(markdown::Playground {
+            crate_name: Some(krate.name.clone()),
+            url,
         });
     }
 
@@ -592,9 +595,9 @@ pub fn run(mut krate: clean::Crate,
                     scx.layout.logo = s.to_string();
                 }
                 (sym::html_playground_url, Some(s)) => {
-                    markdown::PLAYGROUND.with(|slot| {
-                        let name = krate.name.clone();
-                        *slot.borrow_mut() = Some((Some(name), s.to_string()));
+                    playground = Some(markdown::Playground {
+                        crate_name: Some(krate.name.clone()),
+                        url: s.to_string(),
                     });
                 }
                 (sym::issue_tracker_base_url, Some(s)) => {
@@ -618,6 +621,7 @@ pub fn run(mut krate: clean::Crate,
         edition,
         id_map: Rc::new(RefCell::new(id_map)),
         shared: Arc::new(scx),
+        playground,
     };
 
     // Crawl the crate to build various caches used for the output
@@ -2592,7 +2596,7 @@ fn render_markdown(w: &mut fmt::Formatter<'_>,
            if is_hidden { " hidden" } else { "" },
            prefix,
            Markdown(md_text, &links, RefCell::new(&mut ids),
-           cx.codes, cx.edition))
+           cx.codes, cx.edition, &cx.playground))
 }
 
 fn document_short(
@@ -2957,7 +2961,8 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
 
         if let Some(note) = note {
             let mut ids = cx.id_map.borrow_mut();
-            let html = MarkdownHtml(&note, RefCell::new(&mut ids), error_codes, cx.edition);
+            let html = MarkdownHtml(
+                &note, RefCell::new(&mut ids), error_codes, cx.edition, &cx.playground);
             message.push_str(&format!(": {}", html));
         }
         stability.push(format!("<div class='stab deprecated'>{}</div>", message));
@@ -3006,7 +3011,13 @@ fn short_stability(item: &clean::Item, cx: &Context) -> Vec<String> {
             message = format!(
                 "<details><summary>{}</summary>{}</details>",
                 message,
-                MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes, cx.edition)
+                MarkdownHtml(
+                    &unstable_reason,
+                    RefCell::new(&mut ids),
+                    error_codes,
+                    cx.edition,
+                    &cx.playground,
+                )
             );
         }
 
@@ -4237,7 +4248,7 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
             let mut ids = cx.id_map.borrow_mut();
             write!(w, "<div class='docblock'>{}</div>",
                    Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids),
-                            cx.codes, cx.edition))?;
+                            cx.codes, cx.edition, &cx.playground))?;
         }
     }
 
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 50a647f244d..b7dd6c30f09 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -60,9 +60,10 @@ pub fn render(
     };
     let playground_url = options.markdown_playground_url
                             .or(options.playground_url);
-    if let Some(playground) = playground_url {
-        markdown::PLAYGROUND.with(|s| { *s.borrow_mut() = Some((None, playground)); });
-    }
+    let playground = playground_url.map(|url| markdown::Playground {
+        crate_name: None,
+        url,
+    });
 
     let mut out = match File::create(&output) {
         Err(e) => {
@@ -82,9 +83,9 @@ pub fn render(
     let mut ids = IdMap::new();
     let error_codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
     let text = if !options.markdown_no_toc {
-        MarkdownWithToc(text, RefCell::new(&mut ids), error_codes, edition).to_string()
+        MarkdownWithToc(text, RefCell::new(&mut ids), error_codes, edition, &playground).to_string()
     } else {
-        Markdown(text, &[], RefCell::new(&mut ids), error_codes, edition).to_string()
+        Markdown(text, &[], RefCell::new(&mut ids), error_codes, edition, &playground).to_string()
     };
 
     let err = write!(
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index c31a5069e46..33987b0b542 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -16,7 +16,7 @@ use std::cell::RefCell;
 use syntax::edition::DEFAULT_EDITION;
 use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
 
-use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, PLAYGROUND};
+use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, Playground};
 use rustc_serialize::json;
 
 enum OutputFormat {
@@ -95,9 +95,13 @@ impl Formatter for HTMLFormatter {
         match info.description {
             Some(ref desc) => {
                 let mut id_map = self.0.borrow_mut();
+                let playground = Playground {
+                    crate_name: None,
+                    url: String::from("https://play.rust-lang.org/"),
+                };
                 write!(output, "{}",
                     Markdown(desc, &[], RefCell::new(&mut id_map),
-                             ErrorCodes::Yes, DEFAULT_EDITION))?
+                             ErrorCodes::Yes, DEFAULT_EDITION, &Some(playground)))?
             },
             None => write!(output, "<p>No description.</p>\n")?,
         }
@@ -260,9 +264,6 @@ fn parse_args() -> (OutputFormat, PathBuf) {
 
 fn main() {
     env_logger::init();
-    PLAYGROUND.with(|slot| {
-        *slot.borrow_mut() = Some((None, String::from("https://play.rust-lang.org/")));
-    });
     let (format, dst) = parse_args();
     let result = syntax::with_default_globals(move || {
         main_with_result(format, &dst)