Skip to content

Commit 946d76e

Browse files
authored
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... 🙇 )
2 parents 49a31cd + 1b7008d commit 946d76e

File tree

3 files changed

+75
-10
lines changed

3 files changed

+75
-10
lines changed

compiler/rustc_parse/src/lexer/mod.rs

+50-10
Original file line numberDiff line numberDiff line change
@@ -182,16 +182,7 @@ impl<'a> StringReader<'a> {
182182
}
183183
rustc_lexer::TokenKind::BlockComment { doc_style, terminated } => {
184184
if !terminated {
185-
let msg = match doc_style {
186-
Some(_) => "unterminated block doc-comment",
187-
None => "unterminated block comment",
188-
};
189-
let last_bpos = self.pos;
190-
self.sess.span_diagnostic.span_fatal_with_code(
191-
self.mk_sp(start, last_bpos),
192-
msg,
193-
error_code!(E0758),
194-
);
185+
self.report_unterminated_block_comment(start, doc_style);
195186
}
196187

197188
// Skip non-doc comments
@@ -553,6 +544,55 @@ impl<'a> StringReader<'a> {
553544
err.emit()
554545
}
555546

547+
fn report_unterminated_block_comment(&self, start: BytePos, doc_style: Option<DocStyle>) {
548+
let msg = match doc_style {
549+
Some(_) => "unterminated block doc-comment",
550+
None => "unterminated block comment",
551+
};
552+
let last_bpos = self.pos;
553+
let mut err = self.sess.span_diagnostic.struct_span_fatal_with_code(
554+
self.mk_sp(start, last_bpos),
555+
msg,
556+
error_code!(E0758),
557+
);
558+
let mut nested_block_comment_open_idxs = vec![];
559+
let mut last_nested_block_comment_idxs = None;
560+
let mut content_chars = self.str_from(start).char_indices().peekable();
561+
562+
while let Some((idx, current_char)) = content_chars.next() {
563+
match content_chars.peek() {
564+
Some((_, '*')) if current_char == '/' => {
565+
nested_block_comment_open_idxs.push(idx);
566+
}
567+
Some((_, '/')) if current_char == '*' => {
568+
last_nested_block_comment_idxs =
569+
nested_block_comment_open_idxs.pop().map(|open_idx| (open_idx, idx));
570+
}
571+
_ => {}
572+
};
573+
}
574+
575+
if let Some((nested_open_idx, nested_close_idx)) = last_nested_block_comment_idxs {
576+
err.span_label(self.mk_sp(start, start + BytePos(2)), msg)
577+
.span_label(
578+
self.mk_sp(
579+
start + BytePos(nested_open_idx as u32),
580+
start + BytePos(nested_open_idx as u32 + 2),
581+
),
582+
"...as last nested comment starts here, maybe you want to close this instead?",
583+
)
584+
.span_label(
585+
self.mk_sp(
586+
start + BytePos(nested_close_idx as u32),
587+
start + BytePos(nested_close_idx as u32 + 2),
588+
),
589+
"...and last nested comment terminates here.",
590+
);
591+
}
592+
593+
err.emit();
594+
}
595+
556596
// RFC 3101 introduced the idea of (reserved) prefixes. As of Rust 2021,
557597
// using a (unknown) prefix is an error. In earlier editions, however, they
558598
// only result in a (allowed by default) lint, and are treated as regular
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/* //~ ERROR E0758
2+
/* */
3+
/*
4+
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0758]: unterminated block comment
2+
--> $DIR/unterminated-nested-comment.rs:1:1
3+
|
4+
LL | /*
5+
| ^-
6+
| |
7+
| _unterminated block comment
8+
| |
9+
LL | | /* */
10+
LL | | /*
11+
| | --
12+
| | |
13+
| | ...as last nested comment starts here, maybe you want to close this instead?
14+
LL | | */
15+
| |_--^
16+
| |
17+
| ...and last nested comment terminates here.
18+
19+
error: aborting due to previous error
20+
21+
For more information about this error, try `rustc --explain E0758`.

0 commit comments

Comments
 (0)