summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-04-16 07:12:44 +0200
committerGitHub <noreply@github.com>2022-04-16 07:12:44 +0200
commit946d76ec0e3d965bf9a8d3524434abf27db7ecd6 (patch)
treee659cb0c882a12057d1afc45a582120468cd95cb /compiler/rustc_parse/src
parent49a31cdc1df848e9de07687af5c1d3d6fa5edb66 (diff)
parent1b7008dc77e25049b04e5c3e31aecf4de00803e7 (diff)
downloadrust-946d76ec0e3d965bf9a8d3524434abf27db7ecd6.tar.gz
rust-946d76ec0e3d965bf9a8d3524434abf27db7ecd6.zip
Rollup merge of #95859 - rainy-me:unterminated-nested-block-comment, r=petrochenkov
Improve diagnostics for unterminated nested block comment

close #95283

(This is my first time try to messing around with rust compiler and might get a lot of things wrong... :bow: )
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs60
1 files changed, 50 insertions, 10 deletions
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 79f0237fd9b..bfa13ce79ba 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -182,16 +182,7 @@ impl<'a> StringReader<'a> {
             }
             rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => {
                 if !terminated {
-                    let msg = match doc_style {
-                        Some(_) => "unterminated block doc-comment",
-                        None => "unterminated block comment",
-                    };
-                    let last_bpos = self.pos;
-                    self.sess.span_diagnostic.span_fatal_with_code(
-                        self.mk_sp(start, last_bpos),
-                        msg,
-                        error_code!(E0758),
-                    );
+                    self.report_unterminated_block_comment(start, doc_style);
                 }
 
                 // Skip non-doc comments
@@ -553,6 +544,55 @@ impl<'a> StringReader<'a> {
         err.emit()
     }
 
+    fn report_unterminated_block_comment(&self, start: BytePos, doc_style: Option<DocStyle>) {
+        let msg = match doc_style {
+            Some(_) => "unterminated block doc-comment",
+            None => "unterminated block comment",
+        };
+        let last_bpos = self.pos;
+        let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code(
+            self.mk_sp(start, last_bpos),
+            msg,
+            error_code!(E0758),
+        );
+        let mut nested_block_comment_open_idxs = vec![];
+        let mut last_nested_block_comment_idxs = None;
+        let mut content_chars = self.str_from(start).char_indices().peekable();
+
+        while let Some((idx, current_char)) = content_chars.next() {
+            match content_chars.peek() {
+                Some((_, '*')) if current_char == '/' => {
+                    nested_block_comment_open_idxs.push(idx);
+                }
+                Some((_, '/')) if current_char == '*' => {
+                    last_nested_block_comment_idxs =
+                        nested_block_comment_open_idxs.pop().map(|open_idx| (open_idx, idx));
+                }
+                _ => {}
+            };
+        }
+
+        if let Some((nested_open_idx, nested_close_idx)) = last_nested_block_comment_idxs {
+            err.span_label(self.mk_sp(start, start + BytePos(2)), msg)
+                .span_label(
+                    self.mk_sp(
+                        start + BytePos(nested_open_idx as u32),
+                        start + BytePos(nested_open_idx as u32 + 2),
+                    ),
+                    "...as last nested comment starts here, maybe you want to close this instead?",
+                )
+                .span_label(
+                    self.mk_sp(
+                        start + BytePos(nested_close_idx as u32),
+                        start + BytePos(nested_close_idx as u32 + 2),
+                    ),
+                    "...and last nested comment terminates here.",
+                );
+        }
+
+        err.emit();
+    }
+
     // RFC 3101 introduced the idea of (reserved) prefixes. As of Rust 2021,
     // using a (unknown) prefix is an error. In earlier editions, however, they
     // only result in a (allowed by default) lint, and are treated as regular