about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2025-02-12 15:47:18 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2025-02-12 19:46:07 +0100
commit54f59c6ddaafa1b6eb285af0957afa88e2d8e9e8 (patch)
tree364a54ce9bf7f26cef52387a7c1fb3d7cf2b1b3b
parent8c04e395952022a451138dc4dbead6dd6ae65203 (diff)
downloadrust-54f59c6ddaafa1b6eb285af0957afa88e2d8e9e8.tar.gz
rust-54f59c6ddaafa1b6eb285af0957afa88e2d8e9e8.zip
Correctly escape hashtags when running `invalid_rust_codeblocks` lint
-rw-r--r--src/librustdoc/doctest.rs1
-rw-r--r--src/librustdoc/html/markdown.rs8
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs7
3 files changed, 12 insertions, 4 deletions
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 8b522e614b8..4a379b4235f 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -786,6 +786,7 @@ impl IndividualTestOptions {
 /// [`clean`]: crate::clean
 /// [`run_merged_tests`]: crate::doctest::runner::DocTestRunner::run_merged_tests
 /// [`generate_unique_doctest`]: crate::doctest::make::DocTestBuilder::generate_unique_doctest
+#[derive(Debug)]
 pub(crate) struct ScrapedDocTest {
     filename: FileName,
     line: usize,
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 7e835585b73..cb4896f167a 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -140,7 +140,7 @@ impl ErrorCodes {
 /// Controls whether a line will be hidden or shown in HTML output.
 ///
 /// All lines are used in documentation tests.
-enum Line<'a> {
+pub(crate) enum Line<'a> {
     Hidden(&'a str),
     Shown(Cow<'a, str>),
 }
@@ -153,7 +153,7 @@ impl<'a> Line<'a> {
         }
     }
 
-    fn for_code(self) -> Cow<'a, str> {
+    pub(crate) fn for_code(self) -> Cow<'a, str> {
         match self {
             Line::Shown(l) => l,
             Line::Hidden(l) => Cow::Borrowed(l),
@@ -161,12 +161,14 @@ impl<'a> Line<'a> {
     }
 }
 
+/// This function is used to handle the "hidden lines" (ie starting with `#`) in
+/// doctests. It also transforms `##` back into `#`.
 // FIXME: There is a minor inconsistency here. For lines that start with ##, we
 // have no easy way of removing a potential single space after the hashes, which
 // is done in the single # case. This inconsistency seems okay, if non-ideal. In
 // order to fix it we'd have to iterate to find the first non-# character, and
 // then reallocate to remove it; which would make us return a String.
-fn map_line(s: &str) -> Line<'_> {
+pub(crate) fn map_line(s: &str) -> Line<'_> {
     let trimmed = s.trim();
     if trimmed.starts_with("##") {
         Line::Shown(Cow::Owned(s.replacen("##", "#", 1)))
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index 459bdd991db..9662dd85d67 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -1,5 +1,6 @@
 //! Validates syntax inside Rust code blocks (\`\`\`rust).
 
+use std::borrow::Cow;
 use std::sync::Arc;
 
 use rustc_data_structures::sync::Lock;
@@ -43,7 +44,11 @@ fn check_rust_syntax(
 
     let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
     let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
-    let source = dox[code_block.code].to_owned();
+    let source = dox[code_block.code]
+        .lines()
+        .map(|line| crate::html::markdown::map_line(line).for_code())
+        .intersperse(Cow::Borrowed("\n"))
+        .collect::<String>();
     let psess = ParseSess::with_dcx(dcx, sm);
 
     let edition = code_block.lang_string.edition.unwrap_or_else(|| cx.tcx.sess.edition());