diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 72421c9decc6f..d17d27271ce62 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -13,7 +13,7 @@ use rustc::session::config::{nightly_options, build_codegen_options, build_debug
 use rustc::session::search_paths::SearchPath;
 use rustc_driver;
 use rustc_target::spec::TargetTriple;
-use syntax::edition::Edition;
+use syntax::edition::{Edition, DEFAULT_EDITION};
 
 use crate::core::new_handler;
 use crate::externalfiles::ExternalHtml;
@@ -386,6 +386,18 @@ impl Options {
             }
         }
 
+        let edition = if let Some(e) = matches.opt_str("edition") {
+            match e.parse() {
+                Ok(e) => e,
+                Err(_) => {
+                    diag.struct_err("could not parse edition").emit();
+                    return Err(1);
+                }
+            }
+        } else {
+            DEFAULT_EDITION
+        };
+
         let mut id_map = html::markdown::IdMap::new();
         id_map.populate(html::render::initial_ids());
         let external_html = match ExternalHtml::load(
@@ -393,20 +405,12 @@ impl Options {
                 &matches.opt_strs("html-before-content"),
                 &matches.opt_strs("html-after-content"),
                 &matches.opt_strs("markdown-before-content"),
-                &matches.opt_strs("markdown-after-content"), &diag, &mut id_map) {
+                &matches.opt_strs("markdown-after-content"),
+                &diag, &mut id_map, edition) {
             Some(eh) => eh,
             None => return Err(3),
         };
 
-        let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
-        let edition = match edition.parse() {
-            Ok(e) => e,
-            Err(_) => {
-                diag.struct_err("could not parse edition").emit();
-                return Err(1);
-            }
-        };
-
         match matches.opt_str("r").as_ref().map(|s| &**s) {
             Some("rust") | None => {}
             Some(s) => {
diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index 0378b12662da2..d604ba11d4186 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -3,6 +3,7 @@ use std::path::Path;
 use std::str;
 use errors;
 use crate::syntax::feature_gate::UnstableFeatures;
+use crate::syntax::edition::Edition;
 use crate::html::markdown::{IdMap, ErrorCodes, Markdown};
 
 use std::cell::RefCell;
@@ -23,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)
+                id_map: &mut IdMap, edition: Edition)
             -> Option<ExternalHtml> {
         let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
         load_external_files(in_header, diag)
@@ -34,7 +35,8 @@ impl ExternalHtml {
             .and_then(|(ih, bc)|
                 load_external_files(md_before_content, diag)
                     .map(|m_bc| (ih,
-                            format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map), codes))))
+                            format!("{}{}", bc, Markdown(&m_bc, &[], RefCell::new(id_map),
+                                    codes, edition))))
             )
             .and_then(|(ih, bc)|
                 load_external_files(after_content, diag)
@@ -43,7 +45,8 @@ impl ExternalHtml {
             .and_then(|(ih, bc, ac)|
                 load_external_files(md_after_content, diag)
                     .map(|m_ac| (ih, bc,
-                            format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map), codes))))
+                            format!("{}{}", ac, Markdown(&m_ac, &[], RefCell::new(id_map),
+                                    codes, edition))))
             )
             .map(|(ih, bc, ac)|
                 ExternalHtml {
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index a3b041c6954c5..12d10254c4d09 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -8,12 +8,16 @@
 //! ```
 //! #![feature(rustc_private)]
 //!
+//! extern crate syntax;
+//!
+//! use syntax::edition::Edition;
 //! use rustdoc::html::markdown::{IdMap, Markdown, ErrorCodes};
 //! use std::cell::RefCell;
 //!
 //! let s = "My *markdown* _text_";
 //! let mut id_map = IdMap::new();
-//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map), ErrorCodes::Yes));
+//! let html = format!("{}", Markdown(s, &[], RefCell::new(&mut id_map),
+//!                                   ErrorCodes::Yes, Edition::Edition2015));
 //! // ... something using html
 //! ```
 
@@ -42,14 +46,21 @@ fn opts() -> Options {
 /// A unit struct which has the `fmt::Display` trait implemented. When
 /// formatted, this struct will emit the HTML corresponding to the rendered
 /// version of the contained markdown string.
-/// The second parameter is a list of link replacements
+///
+/// The second parameter is a list of link replacements.
+///
+/// The third is the current list of used header IDs.
+///
+/// The fourth is whether to allow the use of explicit error codes in doctest lang strings.
+///
+/// The fifth is what default edition to use when parsing doctests (to add a `fn main`).
 pub struct Markdown<'a>(
-    pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes);
+    pub &'a str, pub &'a [(String, String)], pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
 /// A unit struct like `Markdown`, that renders the markdown with a
 /// table of contents.
-pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes);
+pub struct MarkdownWithToc<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
 /// A unit 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 struct MarkdownHtml<'a>(pub &'a str, pub RefCell<&'a mut IdMap>, pub ErrorCodes, pub Edition);
 /// A unit struct like `Markdown`, that renders only the first paragraph.
 pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]);
 
@@ -146,13 +157,15 @@ thread_local!(pub static PLAYGROUND: RefCell<Option<(Option<String>, String)>> =
 struct CodeBlocks<'a, I: Iterator<Item = Event<'a>>> {
     inner: I,
     check_error_codes: ErrorCodes,
+    edition: Edition,
 }
 
 impl<'a, I: Iterator<Item = Event<'a>>> CodeBlocks<'a, I> {
-    fn new(iter: I, error_codes: ErrorCodes) -> Self {
+    fn new(iter: I, error_codes: ErrorCodes, edition: Edition) -> Self {
         CodeBlocks {
             inner: iter,
             check_error_codes: error_codes,
+            edition,
         }
     }
 }
@@ -177,6 +190,9 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
             return event;
         }
 
+        let explicit_edition = edition.is_some();
+        let edition = edition.unwrap_or(self.edition);
+
         let mut origtext = String::new();
         for event in &mut self.inner {
             match event {
@@ -202,22 +218,14 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
                     .collect::<Vec<Cow<'_, str>>>().join("\n");
                 let krate = krate.as_ref().map(|s| &**s);
                 let (test, _) = test::make_test(&test, krate, false,
-                                           &Default::default());
+                                           &Default::default(), edition);
                 let channel = if test.contains("#![feature(") {
                     "&amp;version=nightly"
                 } else {
                     ""
                 };
 
-                let edition_string = if let Some(e @ Edition::Edition2018) = edition {
-                    format!("&amp;edition={}{}", e,
-                            if channel == "&amp;version=nightly" { "" }
-                            else { "&amp;version=nightly" })
-                } else if let Some(e) = edition {
-                    format!("&amp;edition={}", e)
-                } else {
-                    "".to_owned()
-                };
+                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.
@@ -247,8 +255,8 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
                 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 let Some(e) = edition {
-                Some((format!("This code runs with edition {}", e), "edition"))
+            } else if explicit_edition {
+                Some((format!("This code runs with edition {}", edition), "edition"))
             } else {
                 None
             };
@@ -259,7 +267,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
                     Some(&format!("rust-example-rendered{}",
                                   if ignore { " ignore" }
                                   else if compile_fail { " compile_fail" }
-                                  else if edition.is_some() { " edition " }
+                                  else if explicit_edition { " edition " }
                                   else { "" })),
                     playground_button.as_ref().map(String::as_str),
                     Some((s1.as_str(), s2))));
@@ -270,7 +278,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'a, I> {
                     Some(&format!("rust-example-rendered{}",
                                   if ignore { " ignore" }
                                   else if compile_fail { " compile_fail" }
-                                  else if edition.is_some() { " edition " }
+                                  else if explicit_edition { " edition " }
                                   else { "" })),
                     playground_button.as_ref().map(String::as_str),
                     None));
@@ -659,7 +667,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) = *self;
+        let Markdown(md, links, ref ids, codes, edition) = *self;
         let mut ids = ids.borrow_mut();
 
         // This is actually common enough to special-case
@@ -678,7 +686,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);
+        let p = CodeBlocks::new(p, codes, edition);
         let p = Footnotes::new(p);
         html::push_html(&mut s, p);
 
@@ -688,7 +696,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) = *self;
+        let MarkdownWithToc(md, ref ids, codes, edition) = *self;
         let mut ids = ids.borrow_mut();
 
         let p = Parser::new_ext(md, opts());
@@ -699,7 +707,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
 
         {
             let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
-            let p = CodeBlocks::new(p, codes);
+            let p = CodeBlocks::new(p, codes, edition);
             let p = Footnotes::new(p);
             html::push_html(&mut s, p);
         }
@@ -712,7 +720,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) = *self;
+        let MarkdownHtml(md, ref ids, codes, edition) = *self;
         let mut ids = ids.borrow_mut();
 
         // This is actually common enough to special-case
@@ -728,7 +736,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);
+        let p = CodeBlocks::new(p, codes, edition);
         let p = Footnotes::new(p);
         html::push_html(&mut s, p);
 
@@ -1046,7 +1054,7 @@ mod tests {
     use super::{ErrorCodes, LangString, Markdown, MarkdownHtml, IdMap};
     use super::plain_summary_line;
     use std::cell::RefCell;
-    use syntax::edition::Edition;
+    use syntax::edition::{Edition, DEFAULT_EDITION};
 
     #[test]
     fn test_lang_string_parse() {
@@ -1098,7 +1106,8 @@ mod tests {
     fn test_header() {
         fn t(input: &str, expect: &str) {
             let mut map = IdMap::new();
-            let output = Markdown(input, &[], RefCell::new(&mut map), ErrorCodes::Yes).to_string();
+            let output = Markdown(input, &[], RefCell::new(&mut map),
+                                  ErrorCodes::Yes, DEFAULT_EDITION).to_string();
             assert_eq!(output, expect, "original: {}", input);
         }
 
@@ -1120,7 +1129,8 @@ mod tests {
     fn test_header_ids_multiple_blocks() {
         let mut map = IdMap::new();
         fn t(map: &mut IdMap, input: &str, expect: &str) {
-            let output = Markdown(input, &[], RefCell::new(map), ErrorCodes::Yes).to_string();
+            let output = Markdown(input, &[], RefCell::new(map),
+                                  ErrorCodes::Yes, DEFAULT_EDITION).to_string();
             assert_eq!(output, expect, "original: {}", input);
         }
 
@@ -1157,7 +1167,8 @@ mod tests {
     fn test_markdown_html_escape() {
         fn t(input: &str, expect: &str) {
             let mut idmap = IdMap::new();
-            let output = MarkdownHtml(input, RefCell::new(&mut idmap), ErrorCodes::Yes).to_string();
+            let output = MarkdownHtml(input, RefCell::new(&mut idmap),
+                                      ErrorCodes::Yes, DEFAULT_EDITION).to_string();
             assert_eq!(output, expect, "original: {}", input);
         }
 
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 472192a646492..d92681c4f2350 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -47,6 +47,7 @@ use std::rc::Rc;
 use errors;
 use serialize::json::{ToJson, Json, as_json};
 use syntax::ast;
+use syntax::edition::Edition;
 use syntax::ext::base::MacroKind;
 use syntax::source_map::FileName;
 use syntax::feature_gate::UnstableFeatures;
@@ -107,6 +108,8 @@ struct Context {
     /// publicly reused items to redirect to the right location.
     pub render_redirect_pages: bool,
     pub codes: ErrorCodes,
+    /// The default edition used to parse doctests.
+    pub edition: Edition,
     /// The map used to ensure all generated 'id=' attributes are unique.
     id_map: Rc<RefCell<IdMap>>,
     pub shared: Arc<SharedContext>,
@@ -513,7 +516,8 @@ pub fn run(mut krate: clean::Crate,
            options: RenderOptions,
            passes: FxHashSet<String>,
            renderinfo: RenderInfo,
-           diag: &errors::Handler) -> Result<(), Error> {
+           diag: &errors::Handler,
+           edition: Edition) -> Result<(), Error> {
     // need to save a copy of the options for rendering the index page
     let md_opts = options.clone();
     let RenderOptions {
@@ -603,6 +607,7 @@ pub fn run(mut krate: clean::Crate,
         dst,
         render_redirect_pages: false,
         codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
+        edition,
         id_map: Rc::new(RefCell::new(id_map)),
         shared: Arc::new(scx),
     };
@@ -1127,7 +1132,7 @@ themePicker.onblur = handleThemeButtonsBlur;
             md_opts.output = cx.dst.clone();
             md_opts.external_html = (*cx.shared).layout.external_html.clone();
 
-            crate::markdown::render(index_page, md_opts, diag);
+            crate::markdown::render(index_page, md_opts, diag, cx.edition);
         } else {
             let dst = cx.dst.join("index.html");
             let mut w = BufWriter::new(try_err!(File::create(&dst), &dst));
@@ -2552,7 +2557,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.codes, cx.edition))
 }
 
 fn document_short(
@@ -2917,7 +2922,7 @@ 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);
+            let html = MarkdownHtml(&note, RefCell::new(&mut ids), error_codes, cx.edition);
             message.push_str(&format!(": {}", html));
         }
         stability.push(format!("<div class='stab deprecated'>{}</div>", message));
@@ -2966,7 +2971,7 @@ 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)
+                MarkdownHtml(&unstable_reason, RefCell::new(&mut ids), error_codes, cx.edition)
             );
         }
 
@@ -4179,7 +4184,8 @@ fn render_impl(w: &mut fmt::Formatter<'_>, cx: &Context, i: &Impl, link: AssocIt
         if let Some(ref dox) = cx.shared.maybe_collapsed_doc_value(&i.impl_item) {
             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))?;
+                   Markdown(&*dox, &i.impl_item.links(), RefCell::new(&mut ids),
+                            cx.codes, cx.edition))?;
         }
     }
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 5b76f6861de79..f5061b671828e 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -391,7 +391,10 @@ fn main_args(args: &[String]) -> i32 {
     match (options.should_test, options.markdown_input()) {
         (true, true) => return markdown::test(options, &diag),
         (true, false) => return test::run(options),
-        (false, true) => return markdown::render(options.input, options.render_options, &diag),
+        (false, true) => return markdown::render(options.input,
+                                                 options.render_options,
+                                                 &diag,
+                                                 options.edition),
         (false, false) => {}
     }
 
@@ -399,7 +402,8 @@ fn main_args(args: &[String]) -> i32 {
     // but we can't crates the Handler ahead of time because it's not Send
     let diag_opts = (options.error_format,
                      options.debugging_options.treat_err_as_bug,
-                     options.debugging_options.ui_testing);
+                     options.debugging_options.ui_testing,
+                     options.edition);
     let show_coverage = options.show_coverage;
     rust_input(options, move |out| {
         if show_coverage {
@@ -410,7 +414,7 @@ fn main_args(args: &[String]) -> i32 {
 
         let Output { krate, passes, renderinfo, renderopts } = out;
         info!("going to format");
-        let (error_format, treat_err_as_bug, ui_testing) = diag_opts;
+        let (error_format, treat_err_as_bug, ui_testing, edition) = diag_opts;
         let diag = core::new_handler(error_format, None, treat_err_as_bug, ui_testing);
         match html::render::run(
             krate,
@@ -418,6 +422,7 @@ fn main_args(args: &[String]) -> i32 {
             passes.into_iter().collect(),
             renderinfo,
             &diag,
+            edition,
         ) {
             Ok(_) => rustc_driver::EXIT_SUCCESS,
             Err(e) => {
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index c496dde8426c0..b0a37ea9c8081 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -5,6 +5,7 @@ use std::cell::RefCell;
 
 use errors;
 use testing;
+use syntax::edition::Edition;
 use syntax::source_map::DUMMY_SP;
 use syntax::feature_gate::UnstableFeatures;
 
@@ -36,7 +37,12 @@ fn extract_leading_metadata<'a>(s: &'a str) -> (Vec<&'a str>, &'a str) {
 
 /// Render `input` (e.g., "foo.md") into an HTML file in `output`
 /// (e.g., output = "bar" => "bar/foo.html").
-pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) -> i32 {
+pub fn render(
+    input: PathBuf,
+    options: RenderOptions,
+    diag: &errors::Handler,
+    edition: Edition
+) -> i32 {
     let mut output = options.output;
     output.push(input.file_stem().unwrap());
     output.set_extension("html");
@@ -76,9 +82,9 @@ pub fn render(input: PathBuf, options: RenderOptions, diag: &errors::Handler) ->
     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).to_string()
+        MarkdownWithToc(text, RefCell::new(&mut ids), error_codes, edition).to_string()
     } else {
-        Markdown(text, &[], RefCell::new(&mut ids), error_codes).to_string()
+        Markdown(text, &[], RefCell::new(&mut ids), error_codes, edition).to_string()
     };
 
     let err = write!(
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 5c0a4da1cd7ef..268f0602d4875 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -167,7 +167,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
             maybe_sysroot: Option<PathBuf>, linker: Option<PathBuf>, edition: Edition,
             persist_doctests: Option<PathBuf>) {
     let (test, line_offset) = match panic::catch_unwind(|| {
-        make_test(test, Some(cratename), as_test_harness, opts)
+        make_test(test, Some(cratename), as_test_harness, opts, edition)
     }) {
         Ok((test, line_offset)) => (test, line_offset),
         Err(cause) if cause.is::<errors::FatalErrorMarker>() => {
@@ -356,7 +356,8 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
 pub fn make_test(s: &str,
                  cratename: Option<&str>,
                  dont_insert_main: bool,
-                 opts: &TestOptions)
+                 opts: &TestOptions,
+                 edition: Edition)
                  -> (String, usize) {
     let (crate_attrs, everything_else, crates) = partition_source(s);
     let everything_else = everything_else.trim();
@@ -390,6 +391,8 @@ pub fn make_test(s: &str,
         use errors::emitter::EmitterWriter;
         use errors::Handler;
 
+        syntax::ext::hygiene::set_default_edition(edition);
+
         let filename = FileName::anon_source_code(s);
         let source = crates + &everything_else;
 
@@ -397,6 +400,7 @@ pub fn make_test(s: &str,
         // send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
         let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
         let emitter = EmitterWriter::new(box io::sink(), None, false, false, false);
+        // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
         let handler = Handler::with_emitter(false, None, box emitter);
         let sess = ParseSess::with_span_handler(handler, cm);
 
@@ -880,6 +884,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> {
 #[cfg(test)]
 mod tests {
     use super::{TestOptions, make_test};
+    use syntax::edition::DEFAULT_EDITION;
 
     #[test]
     fn make_test_basic() {
@@ -892,7 +897,7 @@ mod tests {
 fn main() {
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, None, false, &opts);
+        let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
     }
 
@@ -908,7 +913,7 @@ assert_eq!(2+2, 4);
 fn main() {
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, Some("asdf"), false, &opts);
+        let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
     }
 
@@ -927,7 +932,7 @@ fn main() {
 use asdf::qwop;
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, Some("asdf"), false, &opts);
+        let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 3));
     }
 
@@ -949,7 +954,7 @@ fn main() {
 use asdf::qwop;
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, Some("asdf"), false, &opts);
+        let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
     }
 
@@ -968,7 +973,7 @@ fn main() {
 use std::*;
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, Some("std"), false, &opts);
+        let output = make_test(input, Some("std"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
     }
 
@@ -988,7 +993,7 @@ fn main() {
 use asdf::qwop;
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, Some("asdf"), false, &opts);
+        let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
     }
 
@@ -1006,7 +1011,7 @@ fn main() {
 use asdf::qwop;
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, Some("asdf"), false, &opts);
+        let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
     }
 
@@ -1026,7 +1031,7 @@ fn main() {
 use asdf::qwop;
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, Some("asdf"), false, &opts);
+        let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 3));
 
         // Adding more will also bump the returned line offset.
@@ -1039,7 +1044,7 @@ fn main() {
 use asdf::qwop;
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, Some("asdf"), false, &opts);
+        let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 4));
     }
 
@@ -1057,7 +1062,7 @@ assert_eq!(2+2, 4);";
 fn main() {
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, None, false, &opts);
+        let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
     }
 
@@ -1074,7 +1079,7 @@ assert_eq!(2+2, 4);
 fn main() {
     assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, None, false, &opts);
+        let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 1));
     }
 
@@ -1091,7 +1096,7 @@ assert_eq!(2+2, 4);";
 fn main() {
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, None, false, &opts);
+        let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
     }
 
@@ -1106,7 +1111,7 @@ assert_eq!(2+2, 4);";
 "#![allow(unused)]
 //Ceci n'est pas une `fn main`
 assert_eq!(2+2, 4);".to_string();
-        let output = make_test(input, None, true, &opts);
+        let output = make_test(input, None, true, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 1));
     }
 
@@ -1121,7 +1126,7 @@ assert_eq!(2+2, 4);".to_string();
 "fn main() {
 assert_eq!(2+2, 4);
 }".to_string();
-        let output = make_test(input, None, false, &opts);
+        let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 1));
     }
 
@@ -1140,7 +1145,7 @@ fn main() {
 assert_eq!(2+2, 4);
 }".to_string();
 
-        let output = make_test(input, None, false, &opts);
+        let output = make_test(input, None, false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 2));
 
         let input =
@@ -1155,7 +1160,7 @@ fn main() {
 assert_eq!(asdf::foo, 4);
 }".to_string();
 
-        let output = make_test(input, Some("asdf"), false, &opts);
+        let output = make_test(input, Some("asdf"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 3));
     }
 
@@ -1174,7 +1179,7 @@ test_wrapper! {
     fn main() {}
 }".to_string();
 
-        let output = make_test(input, Some("my_crate"), false, &opts);
+        let output = make_test(input, Some("my_crate"), false, &opts, DEFAULT_EDITION);
         assert_eq!(output, (expected, 1));
     }
 }
diff --git a/src/test/rustdoc/async-move-doctest.rs b/src/test/rustdoc/async-move-doctest.rs
new file mode 100644
index 0000000000000..42723132782ca
--- /dev/null
+++ b/src/test/rustdoc/async-move-doctest.rs
@@ -0,0 +1,14 @@
+// compile-flags:--test
+// edition:2018
+
+// prior to setting the default edition for the doctest pre-parser, this doctest would fail due to
+// a fatal parsing error
+// see https://github.com/rust-lang/rust/issues/59313
+
+//! ```
+//! #![feature(async_await)]
+//!
+//! fn foo() {
+//!     drop(async move {});
+//! }
+//! ```
diff --git a/src/test/rustdoc/playground-arg.rs b/src/test/rustdoc/playground-arg.rs
index fb1be7397e65d..018716ad45af3 100644
--- a/src/test/rustdoc/playground-arg.rs
+++ b/src/test/rustdoc/playground-arg.rs
@@ -11,4 +11,4 @@
 pub fn dummy() {}
 
 // ensure that `extern crate foo;` was inserted into code snips automatically:
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D&edition=2015"]' "Run"
diff --git a/src/test/rustdoc/playground.rs b/src/test/rustdoc/playground.rs
index 1b76e6c885349..9971c7b4297a2 100644
--- a/src/test/rustdoc/playground.rs
+++ b/src/test/rustdoc/playground.rs
@@ -24,6 +24,6 @@
 //! }
 //! ```
 
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run"
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D"]' "Run"
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&version=nightly"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&edition=2015"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn%20main()%20%7B%0Aprintln!(%22Hello%2C%20world!%22)%3B%0A%7D&edition=2015"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn%20main()%20%7B%0A%20%20%20%20println!(%22Hello%2C%20world!%22)%3B%0A%7D&version=nightly&edition=2015"]' "Run"
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index 04986b59ea0f1..38bd3fc006dcc 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -15,6 +15,7 @@ use std::path::Path;
 use std::path::PathBuf;
 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};
@@ -97,7 +98,8 @@ impl Formatter for HTMLFormatter {
             Some(ref desc) => {
                 let mut id_map = self.0.borrow_mut();
                 write!(output, "{}",
-                    Markdown(desc, &[], RefCell::new(&mut id_map), ErrorCodes::Yes))?
+                    Markdown(desc, &[], RefCell::new(&mut id_map),
+                             ErrorCodes::Yes, DEFAULT_EDITION))?
             },
             None => write!(output, "<p>No description.</p>\n")?,
         }