@@ -182,16 +182,7 @@ impl<'a> StringReader<'a> {
182
182
}
183
183
rustc_lexer:: TokenKind :: BlockComment { doc_style, terminated } => {
184
184
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) ;
195
186
}
196
187
197
188
// Skip non-doc comments
@@ -553,6 +544,55 @@ impl<'a> StringReader<'a> {
553
544
err. emit ( )
554
545
}
555
546
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
+
556
596
// RFC 3101 introduced the idea of (reserved) prefixes. As of Rust 2021,
557
597
// using a (unknown) prefix is an error. In earlier editions, however, they
558
598
// only result in a (allowed by default) lint, and are treated as regular
0 commit comments