about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock47
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/html/markdown.rs117
-rw-r--r--src/librustdoc/markdown.rs7
-rw-r--r--src/librustdoc/passes/mod.rs36
-rw-r--r--src/librustdoc/test.rs6
-rw-r--r--src/test/run-make-fulldeps/rustdoc-error-lines/Makefile5
-rw-r--r--src/test/run-make-fulldeps/rustdoc-error-lines/input.rs17
8 files changed, 113 insertions, 124 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4c493b25fd9..b62c7ff9097 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,7 +10,7 @@ name = "aho-corasick"
 version = "0.6.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -972,7 +972,7 @@ name = "fwdansi"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1027,7 +1027,7 @@ dependencies = [
  "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1143,7 +1143,7 @@ dependencies = [
  "globset 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1441,7 +1441,7 @@ dependencies = [
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1469,7 +1469,7 @@ dependencies = [
  "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1494,13 +1494,8 @@ dependencies = [
 
 [[package]]
 name = "memchr"
-version = "2.1.1"
+version = "2.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)",
- "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
 
 [[package]]
 name = "memmap"
@@ -2005,6 +2000,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "pulldown-cmark"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "quick-error"
 version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2169,7 +2174,7 @@ version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2181,7 +2186,7 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3015,7 +3020,7 @@ version = "0.0.0"
 dependencies = [
  "minifier 0.0.29 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pulldown-cmark 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -3775,6 +3780,14 @@ version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
+name = "unicase"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "unicode-bidi"
 version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4132,7 +4145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum mdbook 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "90b5a8d7e341ceee5db3882a06078d42661ddcfa2b3687319cc5da76ec4e782f"
 "checksum mdbook 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0ba0d44cb4089c741b9a91f3e5218298a40699c2f3a070a85014eed290c60819"
 "checksum measureme 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "36bb2b263a6795d352035024d6b30ce465bb79a5e5280d74c3b5f8464c657bcc"
-"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16"
+"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39"
 "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
 "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
 "checksum minifier 0.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1f4950cb2617b1933e2da0446e864dfe0d6a22c22ff72297996c46e6a63b210b"
@@ -4184,6 +4197,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum proptest 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24f5844db2f839e97e3021980975f6ebf8691d9b9b2ca67ed3feb38dc3edb52c"
 "checksum pulldown-cmark 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d6fdf85cda6cadfae5428a54661d431330b312bc767ddbc57adbedc24da66e32"
 "checksum pulldown-cmark 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eef52fac62d0ea7b9b4dc7da092aa64ea7ec3d90af6679422d3d7e0e14b6ee15"
+"checksum pulldown-cmark 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d1b74cc784b038a9921fd1a48310cc2e238101aa8ae0b94201e2d85121dd68b5"
 "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
 "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
@@ -4293,6 +4307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
 "checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
 "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
+"checksum unicase 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41d17211f887da8e4a70a45b9536f26fc5de166b81e2d5d80de4a17fd22553bd"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
 "checksum unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6a0180bc61fc5a987082bfa111f4cc95c4caff7f9799f3e46df09163a937aa25"
 "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 4d2c03a4f2f..4941867d8df 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -9,7 +9,7 @@ name = "rustdoc"
 path = "lib.rs"
 
 [dependencies]
-pulldown-cmark = { version = "0.1.2", default-features = false }
+pulldown-cmark = { version = "0.4.1", default-features = false }
 minifier = "0.0.29"
 tempfile = "3"
 parking_lot = "0.7"
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index a70fe363ca6..a3b041c6954 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -33,8 +33,11 @@ use crate::html::toc::TocBuilder;
 use crate::html::highlight;
 use crate::test;
 
-use pulldown_cmark::{html, Event, Tag, Parser};
-use pulldown_cmark::{Options, OPTION_ENABLE_FOOTNOTES, OPTION_ENABLE_TABLES};
+use pulldown_cmark::{html, CowStr, Event, Options, Parser, Tag};
+
+fn opts() -> Options {
+    Options::ENABLE_TABLES | Options::ENABLE_FOOTNOTES
+}
 
 /// A unit struct which has the `fmt::Display` trait implemented. When
 /// formatted, this struct will emit the HTML corresponding to the rendered
@@ -297,12 +300,11 @@ impl<'a, 'b, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, 'b, I>
 
     fn next(&mut self) -> Option<Self::Item> {
         let event = self.inner.next();
-        if let Some(Event::Start(Tag::Link(dest, text))) = event {
-            if let Some(&(_, ref replace)) = self.links.into_iter().find(|link| &*link.0 == &*dest)
-            {
-                Some(Event::Start(Tag::Link(replace.to_owned().into(), text)))
+        if let Some(Event::Start(Tag::Link(kind, dest, text))) = event {
+            if let Some(&(_, ref replace)) = self.links.iter().find(|link| link.0 == *dest) {
+                Some(Event::Start(Tag::Link(kind, replace.to_owned().into(), text)))
             } else {
-                Some(Event::Start(Tag::Link(dest, text)))
+                Some(Event::Start(Tag::Link(kind, dest, text)))
             }
         } else {
             event
@@ -393,7 +395,7 @@ fn check_if_allowed_tag(t: &Tag<'_>) -> bool {
         | Tag::Emphasis
         | Tag::Strong
         | Tag::Code
-        | Tag::Link(_, _)
+        | Tag::Link(..)
         | Tag::BlockQuote => true,
         _ => false,
     }
@@ -520,63 +522,39 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
     }
 }
 
-pub struct TestableCodeError(());
-
-impl fmt::Display for TestableCodeError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        write!(f, "invalid start of a new code block")
-    }
-}
-
-pub fn find_testable_code<T: test::Tester>(
-    doc: &str,
-    tests: &mut T,
-    error_codes: ErrorCodes,
-) -> Result<(), TestableCodeError> {
+pub fn find_testable_code<T: test::Tester>(doc: &str, tests: &mut T, error_codes: ErrorCodes) {
     let mut parser = Parser::new(doc);
     let mut prev_offset = 0;
     let mut nb_lines = 0;
     let mut register_header = None;
-    'main: while let Some(event) = parser.next() {
+    while let Some(event) = parser.next() {
         match event {
             Event::Start(Tag::CodeBlock(s)) => {
+                let offset = parser.get_offset();
+
                 let block_info = if s.is_empty() {
                     LangString::all_false()
                 } else {
                     LangString::parse(&*s, error_codes)
                 };
                 if !block_info.rust {
-                    continue
+                    continue;
                 }
                 let mut test_s = String::new();
-                let mut offset = None;
-                loop {
-                    let event = parser.next();
-                    if let Some(event) = event {
-                        match event {
-                            Event::End(Tag::CodeBlock(_)) => break,
-                            Event::Text(ref s) => {
-                                test_s.push_str(s);
-                                if offset.is_none() {
-                                    offset = Some(parser.get_offset());
-                                }
-                            }
-                            _ => {}
-                        }
-                    } else {
-                        break 'main;
-                    }
-                }
-                if let Some(offset) = offset {
-                    let lines = test_s.lines().map(|l| map_line(l).for_code());
-                    let text = lines.collect::<Vec<Cow<'_, str>>>().join("\n");
-                    nb_lines += doc[prev_offset..offset].lines().count();
-                    let line = tests.get_line() + (nb_lines - 1);
-                    tests.add_test(text, block_info, line);
-                    prev_offset = offset;
-                } else {
-                    return Err(TestableCodeError(()));
+
+                while let Some(Event::Text(s)) = parser.next() {
+                    test_s.push_str(&s);
                 }
+
+                let text = test_s
+                    .lines()
+                    .map(|l| map_line(l).for_code())
+                    .collect::<Vec<Cow<'_, str>>>()
+                    .join("\n");
+                nb_lines += doc[prev_offset..offset].lines().count();
+                let line = tests.get_line() + nb_lines;
+                tests.add_test(text, block_info, line);
+                prev_offset = offset;
             }
             Event::Start(Tag::Header(level)) => {
                 register_header = Some(level as u32);
@@ -593,7 +571,6 @@ pub fn find_testable_code<T: test::Tester>(
             _ => {}
         }
     }
-    Ok(())
 }
 
 #[derive(Eq, PartialEq, Clone, Debug)]
@@ -687,10 +664,6 @@ impl<'a> fmt::Display for Markdown<'a> {
 
         // This is actually common enough to special-case
         if md.is_empty() { return Ok(()) }
-        let mut opts = Options::empty();
-        opts.insert(OPTION_ENABLE_TABLES);
-        opts.insert(OPTION_ENABLE_FOOTNOTES);
-
         let replacer = |_: &str, s: &str| {
             if let Some(&(_, ref replace)) = links.into_iter().find(|link| &*link.0 == s) {
                 Some((replace.clone(), s.to_owned()))
@@ -699,7 +672,7 @@ impl<'a> fmt::Display for Markdown<'a> {
             }
         };
 
-        let p = Parser::new_with_broken_link_callback(md, opts, Some(&replacer));
+        let p = Parser::new_with_broken_link_callback(md, opts(), Some(&replacer));
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
@@ -718,11 +691,7 @@ impl<'a> fmt::Display for MarkdownWithToc<'a> {
         let MarkdownWithToc(md, ref ids, codes) = *self;
         let mut ids = ids.borrow_mut();
 
-        let mut opts = Options::empty();
-        opts.insert(OPTION_ENABLE_TABLES);
-        opts.insert(OPTION_ENABLE_FOOTNOTES);
-
-        let p = Parser::new_ext(md, opts);
+        let p = Parser::new_ext(md, opts());
 
         let mut s = String::with_capacity(md.len() * 3 / 2);
 
@@ -748,11 +717,7 @@ impl<'a> fmt::Display for MarkdownHtml<'a> {
 
         // This is actually common enough to special-case
         if md.is_empty() { return Ok(()) }
-        let mut opts = Options::empty();
-        opts.insert(OPTION_ENABLE_TABLES);
-        opts.insert(OPTION_ENABLE_FOOTNOTES);
-
-        let p = Parser::new_ext(md, opts);
+        let p = Parser::new_ext(md, opts());
 
         // Treat inline HTML as plain text.
         let p = p.map(|event| match event {
@@ -868,10 +833,6 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
         return vec![];
     }
 
-    let mut opts = Options::empty();
-    opts.insert(OPTION_ENABLE_TABLES);
-    opts.insert(OPTION_ENABLE_FOOTNOTES);
-
     let mut links = vec![];
     let shortcut_links = RefCell::new(vec![]);
 
@@ -894,8 +855,7 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
             shortcut_links.borrow_mut().push((s.to_owned(), locate(s)));
             None
         };
-        let p = Parser::new_with_broken_link_callback(md, opts,
-            Some(&push));
+        let p = Parser::new_with_broken_link_callback(md, opts(), Some(&push));
 
         // There's no need to thread an IdMap through to here because
         // the IDs generated aren't going to be emitted anywhere.
@@ -903,11 +863,11 @@ pub fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
         let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids));
 
         for ev in iter {
-            if let Event::Start(Tag::Link(dest, _)) = ev {
+            if let Event::Start(Tag::Link(_, dest, _)) = ev {
                 debug!("found link: {}", dest);
                 links.push(match dest {
-                    Cow::Borrowed(s) => (s.to_owned(), locate(s)),
-                    Cow::Owned(s) => (s, None),
+                    CowStr::Borrowed(s) => (s.to_owned(), locate(s)),
+                    s @ CowStr::Boxed(..) | s @ CowStr::Inlined(..) => (s.into_string(), None),
                 });
             }
         }
@@ -939,10 +899,7 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
         return code_blocks;
     }
 
-    let mut opts = Options::empty();
-    opts.insert(OPTION_ENABLE_TABLES);
-    opts.insert(OPTION_ENABLE_FOOTNOTES);
-    let mut p = Parser::new_ext(md, opts);
+    let mut p = Parser::new_ext(md, opts());
 
     let mut code_block_start = 0;
     let mut code_start = 0;
@@ -1013,7 +970,7 @@ crate fn rust_code_blocks(md: &str) -> Vec<RustCodeBlock> {
                         end: code_end,
                     },
                     syntax: if !syntax.is_empty() {
-                        Some(syntax.into_owned())
+                        Some(syntax.into_string())
                     } else {
                         None
                     },
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index a2e2303bb27..c496dde8426 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -143,10 +143,9 @@ pub fn test(mut options: Options, diag: &errors::Handler) -> i32 {
                                        options.linker, options.edition, options.persist_doctests);
     collector.set_position(DUMMY_SP);
     let codes = ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build());
-    let res = find_testable_code(&input_str, &mut collector, codes);
-    if let Err(err) = res {
-        diag.span_warn(DUMMY_SP, &err.to_string());
-    }
+
+    find_testable_code(&input_str, &mut collector, codes);
+
     options.test_args.insert(0, "rustdoctest".to_string());
     testing::test_main(&options.test_args, collector.tests,
                        testing::Options::new().display_output(options.display_warnings));
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 3c403d421c8..99aca063471 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -333,24 +333,24 @@ pub fn look_for_tests<'tcx>(
         found_tests: 0,
     };
 
-    if find_testable_code(&dox, &mut tests, ErrorCodes::No).is_ok() {
-        if check_missing_code == true && tests.found_tests == 0 {
-            let mut diag = cx.tcx.struct_span_lint_hir(
-                lint::builtin::MISSING_DOC_CODE_EXAMPLES,
-                hir::CRATE_HIR_ID,
-                span_of_attrs(&item.attrs),
-                "Missing code example in this documentation");
-            diag.emit();
-        } else if check_missing_code == false &&
-                  tests.found_tests > 0 &&
-                  !cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) {
-            let mut diag = cx.tcx.struct_span_lint_hir(
-                lint::builtin::PRIVATE_DOC_TESTS,
-                hir::CRATE_HIR_ID,
-                span_of_attrs(&item.attrs),
-                "Documentation test in private item");
-            diag.emit();
-        }
+    find_testable_code(&dox, &mut tests, ErrorCodes::No);
+
+    if check_missing_code == true && tests.found_tests == 0 {
+        let mut diag = cx.tcx.struct_span_lint_hir(
+            lint::builtin::MISSING_DOC_CODE_EXAMPLES,
+            hir::CRATE_HIR_ID,
+            span_of_attrs(&item.attrs),
+            "Missing code example in this documentation");
+        diag.emit();
+    } else if check_missing_code == false &&
+              tests.found_tests > 0 &&
+              !cx.renderinfo.borrow().access_levels.is_doc_reachable(item.def_id) {
+        let mut diag = cx.tcx.struct_span_lint_hir(
+            lint::builtin::PRIVATE_DOC_TESTS,
+            hir::CRATE_HIR_ID,
+            span_of_attrs(&item.attrs),
+            "Documentation test in private item");
+        diag.emit();
     }
 }
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index abf74158c93..849298698af 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -796,11 +796,7 @@ impl<'a, 'hir> HirCollector<'a, 'hir> {
         // anything else, this will combine them for us.
         if let Some(doc) = attrs.collapsed_doc_value() {
             self.collector.set_position(attrs.span.unwrap_or(DUMMY_SP));
-            let res = markdown::find_testable_code(&doc, self.collector, self.codes);
-            if let Err(err) = res {
-                self.sess.diagnostic().span_warn(attrs.span.unwrap_or(DUMMY_SP),
-                    &err.to_string());
-            }
+            markdown::find_testable_code(&doc, self.collector, self.codes);
         }
 
         nested(self);
diff --git a/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile b/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile
index e09343aa937..c9d41f0ec3b 100644
--- a/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile
+++ b/src/test/run-make-fulldeps/rustdoc-error-lines/Makefile
@@ -5,4 +5,9 @@
 
 all:
 	$(RUSTDOC) --test input.rs > $(TMPDIR)/output || true
+	$(CGREP) 'input.rs - foo (line 5)' < $(TMPDIR)/output
 	$(CGREP) 'input.rs:7:15' < $(TMPDIR)/output
+	$(CGREP) 'input.rs - bar (line 15)' < $(TMPDIR)/output
+	$(CGREP) 'input.rs:17:15' < $(TMPDIR)/output
+	$(CGREP) 'input.rs - bar (line 24)' < $(TMPDIR)/output
+	$(CGREP) 'input.rs:26:15' < $(TMPDIR)/output
diff --git a/src/test/run-make-fulldeps/rustdoc-error-lines/input.rs b/src/test/run-make-fulldeps/rustdoc-error-lines/input.rs
index 7b07f38f259..2d29fa89110 100644
--- a/src/test/run-make-fulldeps/rustdoc-error-lines/input.rs
+++ b/src/test/run-make-fulldeps/rustdoc-error-lines/input.rs
@@ -9,3 +9,20 @@
 pub fn foo() {
 
 }
+
+/// Add some text around the test...
+///
+/// ```rust
+/// #![feature(nll)]
+/// let x: char = 1;
+/// ```
+///
+/// ...to make sure that the line number is still correct.
+///
+/// Let's also add a second test in the same doc comment.
+///
+/// ```rust
+/// #![feature(nll)]
+/// let x: char = 1;
+/// ```
+pub fn bar() {}