about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-09-08 12:55:15 +0000
committerbors <bors@rust-lang.org>2021-09-08 12:55:15 +0000
commitc9db3e0fbc84d8409285698486375f080d361ef3 (patch)
treeb44b6179fe3798d2e3c12fd6de2fb3a43869884d /src
parent434cb437b55d61bcb54a01921de7ac752e6dee13 (diff)
parente66dafcd247d542198b31bd413f65906facd4fd4 (diff)
downloadrust-c9db3e0fbc84d8409285698486375f080d361ef3.tar.gz
rust-c9db3e0fbc84d8409285698486375f080d361ef3.zip
Auto merge of #87489 - bdalrhm:rustdoc-line-num, r=CraftSpider
`rustdoc`: compute correct line number for indented rust code blocks.

This PR fixes a bug in `rustdoc` where it computes the wrong line number for indented rust code blocks (and subsequent blocks) it finds in markdown strings. To fix this issue, we decrement the line number if we find characters between the code block and the preceding line ending. I noticed this issue as I was trying to use `rustdoc` to extract examples from The Rust Reference and run them through the [Rust Model Checker](https://github.com/model-checking/rmc).
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/html/markdown.rs6
-rw-r--r--src/librustdoc/html/markdown/tests.rs24
2 files changed, 29 insertions, 1 deletions
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index aa3723eddfc..5cd5254f328 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -692,6 +692,12 @@ crate fn find_testable_code<T: doctest::Tester>(
                     .join("\n");
 
                 nb_lines += doc[prev_offset..offset.start].lines().count();
+                // If there are characters between the preceding line ending and
+                // this code block, `str::lines` will return an additional line,
+                // which we subtract here.
+                if nb_lines != 0 && !&doc[prev_offset..offset.start].ends_with("\n") {
+                    nb_lines -= 1;
+                }
                 let line = tests.get_line() + nb_lines + 1;
                 tests.add_test(text, block_info, line);
                 prev_offset = offset.start;
diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs
index eca75ef013a..1e4cf3381f6 100644
--- a/src/librustdoc/html/markdown/tests.rs
+++ b/src/librustdoc/html/markdown/tests.rs
@@ -1,4 +1,4 @@
-use super::{plain_text_summary, short_markdown_summary};
+use super::{find_testable_code, plain_text_summary, short_markdown_summary};
 use super::{ErrorCodes, IdMap, Ignore, LangString, Markdown, MarkdownHtml};
 use rustc_span::edition::{Edition, DEFAULT_EDITION};
 
@@ -300,3 +300,25 @@ fn test_markdown_html_escape() {
     t("Struct<'a, T>", "<p>Struct&lt;’a, T&gt;</p>\n");
     t("Struct<br>", "<p>Struct&lt;br&gt;</p>\n");
 }
+
+#[test]
+fn test_find_testable_code_line() {
+    fn t(input: &str, expect: &[usize]) {
+        impl crate::doctest::Tester for Vec<usize> {
+            fn add_test(&mut self, _test: String, _config: LangString, line: usize) {
+                self.push(line);
+            }
+        }
+        let mut lines = Vec::<usize>::new();
+        find_testable_code(input, &mut lines, ErrorCodes::No, false, None);
+        assert_eq!(lines, expect);
+    }
+
+    t("", &[]);
+    t("```rust\n```", &[1]);
+    t(" ```rust\n```", &[1]);
+    t("\n```rust\n```", &[2]);
+    t("\n ```rust\n```", &[2]);
+    t("```rust\n```\n```rust\n```", &[1, 3]);
+    t("```rust\n```\n ```rust\n```", &[1, 3]);
+}