Skip to content

rustdoc: provide more context for parse errors in code blocks #67857

Open
@euclio

Description

@euclio
Contributor

Split from #67563.

Currently, the bad_codeblock_syntax_pass in rustdoc provides error messages like the following:

warning: could not parse code block as Rust code
  --> $DIR/invalid-syntax.rs:3:5
   |
LL |   /// ```
   |  _____^
LL | | /// \__________pkt->size___________/          \_result->size_/ \__pkt->size__/
LL | | /// ```
   | |_______^
   |
   = note: error from rustc: unknown start of token: \
   = note: error from rustc: unknown start of token: \
   = note: error from rustc: unknown start of token: \

Ideally, we could display the error spans inline (but downgrade them to warnings).

Activity

added
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.
on Jan 4, 2020
added
A-diagnosticsArea: Messages for errors, warnings, and lints
A-parserArea: The lexing & parsing of Rust source code to an AST
on Jan 4, 2020
jyn514

jyn514 commented on Dec 15, 2020

@jyn514
Member

Triage: the errors are still the same on 1.50 nightly.

jyn514

jyn514 commented on May 4, 2021

@jyn514
Member

I tried this change:

diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 74d396efd57..11c59d6326a 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -111,11 +111,14 @@ fn check_rust_syntax(&self, item: &clean::Item, dox: &str, code_block: RustCodeB
                 diag.help(&format!("{}: ```text", explanation));
             }
 
-            // FIXME(#67563): Provide more context for these errors by displaying the spans inline.
-            for message in buffer.messages.iter() {
-                diag.note(&message);
+            for new_diag in &buffer.messages {
+                if let Some(sp) = new_diag.span.primary_span() {
+                    diag.span_warn(dbg!(sp), &new_diag.message());
+                } else {
+                    diag.warn(&new_diag.message());
+                }
+                diag.suggestions.extend(new_diag.suggestions.clone());
             }
-
             diag.emit();
         };
 
@@ -147,7 +150,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
 
 #[derive(Default)]
 struct Buffer {
-    messages: Vec<String>,
+    messages: Vec<Diagnostic>,
     has_errors: bool,
 }
 
@@ -158,7 +161,9 @@ struct BufferEmitter {
 impl Emitter for BufferEmitter {
     fn emit_diagnostic(&mut self, diag: &Diagnostic) {
         let mut buffer = self.buffer.borrow_mut();
-        buffer.messages.push(format!("error from rustc: {}", diag.message[0].0));
+        let mut formatted_diag = diag.clone();
+        formatted_diag.message[0].0 = format!("error from rustc: {}", diag.message[0].0);
+        buffer.messages.push(formatted_diag);
         if diag.is_error() {
             buffer.has_errors = true;
         }

Unfortunately it doesn't work very well; I think the spans don't match up between sessions.

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: `#[warn(rustdoc::invalid_rust_codeblocks)]` on by default
help: `ignore` code blocks require valid Rust code for syntax highlighting; mark blocks that do not contain Rust code as text: ```text
  --> $DIR/ignore-block-help.rs:3:5
   |
LL | /// ```ignore (to-prevent-tidy-error)
   |     ^^^
warning: error from rustc: character literal may only contain one codepoint
  --> $DIR/ignore-block-help.rs:1:13
   |
LL |   // check-pass
   |  _____________^
LL | |
LL | | /// ```ignore (to-prevent-tidy-error)
   | |_____^
help: if you meant to write a `str` literal, use double quotes
   |
LL | // check-pas"❤️"``ignore (to-prevent-tidy-error)
   |             ^^^

warning: 1 warning emitted
jyn514

jyn514 commented on May 4, 2021

@jyn514
Member

This also doesn't work well:

            for new_diag in &buffer.messages {
                diag.warn(&new_diag.message());
                for (span, label) in new_diag.span.labels {
                    diag.span_note(span, label);
                }
                diag.suggestions.extend(new_diag.suggestions.clone());
            }
warning: error from rustc: character literal may only contain one codepoint
  --> $DIR/ignore-block-help.rs:1:13
   |
LL |   // check-pass
   |  _____________^
LL | |
LL | | /// ```ignore (to-prevent-tidy-error)
   | |_____^
help: if you meant to write a `str` literal, use double quotes
   |
LL | // check-pas"❤️"``ignore (to-prevent-tidy-error)
   |             ^^^
camelid

camelid commented on May 5, 2021

@camelid
Member

This also doesn't work well:

            for new_diag in &buffer.messages {
                diag.warn(&new_diag.message());
                for (span, label) in new_diag.span.labels {
                    diag.span_note(span, label);
                }
                diag.suggestions.extend(new_diag.suggestions.clone());
            }
warning: error from rustc: character literal may only contain one codepoint
  --> $DIR/ignore-block-help.rs:1:13
   |
LL |   // check-pass
   |  _____________^
LL | |
LL | | /// ```ignore (to-prevent-tidy-error)
   | |_____^
help: if you meant to write a `str` literal, use double quotes
   |
LL | // check-pas"❤️"``ignore (to-prevent-tidy-error)
   |             ^^^

That's just because you need to offset the span by the position of the start of the codeblock (the ```).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-parserArea: The lexing & parsing of Rust source code to an ASTC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @euclio@jonas-schievink@jyn514@JohnTitor@camelid

        Issue actions

          rustdoc: provide more context for parse errors in code blocks · Issue #67857 · rust-lang/rust