about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2021-01-03 17:09:01 +0100
committerGitHub <noreply@github.com>2021-01-03 17:09:01 +0100
commit2686daa7791865d7970fba2b9d6e6db279666a41 (patch)
treeb4c100285b7fa8e271f16feb3ba6af74ea0cacbb
parentbcd69750794b315d7c673351f86cacdf5232a0b7 (diff)
parent7bc1eb4506170e0750de4757af97f341c427a35a (diff)
downloadrust-2686daa7791865d7970fba2b9d6e6db279666a41.tar.gz
rust-2686daa7791865d7970fba2b9d6e6db279666a41.zip
Rollup merge of #80580 - GuillaumeGomez:suggestion-ignore-codeblock-warn, r=jyn514
Add suggestion for "ignore" doc code block

Part of https://github.com/rust-lang/rust/issues/30032.

This PR adds a suggestion to help users when they have a "ignore" doc code block which is invalid rust code.

r? `@jyn514`
-rw-r--r--src/librustdoc/html/markdown.rs12
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs15
-rw-r--r--src/test/rustdoc-ui/ignore-block-help.rs7
-rw-r--r--src/test/rustdoc-ui/ignore-block-help.stderr17
4 files changed, 45 insertions, 6 deletions
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 07744139605..0a8c89f6caf 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1193,6 +1193,7 @@ crate struct RustCodeBlock {
     crate code: Range<usize>,
     crate is_fenced: bool,
     crate syntax: Option<String>,
+    crate is_ignore: bool,
 }
 
 /// Returns a range of bytes for each code block in the markdown that is tagged as `rust` or
@@ -1208,7 +1209,7 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec<RustC
 
     while let Some((event, offset)) = p.next() {
         if let Event::Start(Tag::CodeBlock(syntax)) = event {
-            let (syntax, code_start, code_end, range, is_fenced) = match syntax {
+            let (syntax, code_start, code_end, range, is_fenced, is_ignore) = match syntax {
                 CodeBlockKind::Fenced(syntax) => {
                     let syntax = syntax.as_ref();
                     let lang_string = if syntax.is_empty() {
@@ -1219,6 +1220,7 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec<RustC
                     if !lang_string.rust {
                         continue;
                     }
+                    let is_ignore = lang_string.ignore != Ignore::None;
                     let syntax = if syntax.is_empty() { None } else { Some(syntax.to_owned()) };
                     let (code_start, mut code_end) = match p.next() {
                         Some((Event::Text(_), offset)) => (offset.start, offset.end),
@@ -1229,6 +1231,7 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec<RustC
                                 range: offset,
                                 code,
                                 syntax,
+                                is_ignore,
                             });
                             continue;
                         }
@@ -1239,6 +1242,7 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec<RustC
                                 range: offset,
                                 code,
                                 syntax,
+                                is_ignore,
                             });
                             continue;
                         }
@@ -1246,7 +1250,7 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec<RustC
                     while let Some((Event::Text(_), offset)) = p.next() {
                         code_end = offset.end;
                     }
-                    (syntax, code_start, code_end, offset, true)
+                    (syntax, code_start, code_end, offset, true, is_ignore)
                 }
                 CodeBlockKind::Indented => {
                     // The ending of the offset goes too far sometime so we reduce it by one in
@@ -1258,9 +1262,10 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec<RustC
                             offset.end,
                             Range { start: offset.start, end: offset.end - 1 },
                             false,
+                            false,
                         )
                     } else {
-                        (None, offset.start, offset.end, offset, false)
+                        (None, offset.start, offset.end, offset, false, false)
                     }
                 }
             };
@@ -1270,6 +1275,7 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_, '_>) -> Vec<RustC
                 range,
                 code: Range { start: code_start, end: code_end },
                 syntax,
+                is_ignore,
             });
         }
     }
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 0c76dc571be..554392c213e 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -51,10 +51,10 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
             let mut diag = if let Some(sp) =
                 super::source_span_for_markdown_range(self.cx, &dox, &code_block.range, &item.attrs)
             {
-                let warning_message = if buffer.has_errors {
-                    "could not parse code block as Rust code"
+                let (warning_message, suggest_using_text) = if buffer.has_errors {
+                    ("could not parse code block as Rust code", true)
                 } else {
-                    "Rust code block is empty"
+                    ("Rust code block is empty", false)
                 };
 
                 let mut diag = self.cx.sess().struct_span_warn(sp, warning_message);
@@ -67,6 +67,15 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
                         String::from("```text"),
                         Applicability::MachineApplicable,
                     );
+                } else if suggest_using_text && code_block.is_ignore {
+                    let sp = sp.from_inner(InnerSpan::new(0, 3));
+                    diag.span_suggestion(
+                        sp,
+                        "`ignore` code blocks require valid Rust code for syntax highlighting. \
+                         Mark blocks that do not contain Rust code as text",
+                        String::from("```text,"),
+                        Applicability::MachineApplicable,
+                    );
                 }
 
                 diag
diff --git a/src/test/rustdoc-ui/ignore-block-help.rs b/src/test/rustdoc-ui/ignore-block-help.rs
new file mode 100644
index 00000000000..c22dddd11df
--- /dev/null
+++ b/src/test/rustdoc-ui/ignore-block-help.rs
@@ -0,0 +1,7 @@
+// check-pass
+
+/// ```ignore (to-prevent-tidy-error)
+/// let heart = '❤️';
+/// ```
+//~^^^ WARN
+pub struct X;
diff --git a/src/test/rustdoc-ui/ignore-block-help.stderr b/src/test/rustdoc-ui/ignore-block-help.stderr
new file mode 100644
index 00000000000..d45cd92d2d1
--- /dev/null
+++ b/src/test/rustdoc-ui/ignore-block-help.stderr
@@ -0,0 +1,17 @@
+warning: could not parse code block as Rust code
+  --> $DIR/ignore-block-help.rs:3:5
+   |
+LL |   /// ```ignore (to-prevent-tidy-error)
+   |  _____^
+LL | | /// let heart = '❤️';
+LL | | /// ```
+   | |_______^
+   |
+   = note: error from rustc: character literal may only contain one codepoint
+help: `ignore` code blocks require valid Rust code for syntax highlighting. Mark blocks that do not contain Rust code as text
+   |
+LL | /// ```text,ignore (to-prevent-tidy-error)
+   |     ^^^^^^^^
+
+warning: 1 warning emitted
+