@@ -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,58 @@ 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 ( ) ;
561
+
562
+ if let Some ( ( _, mut last_char) ) = content_chars. next ( ) {
563
+ while let Some ( ( idx, c) ) = content_chars. next ( ) {
564
+ match c {
565
+ '*' if last_char == '/' => {
566
+ nested_block_comment_open_idxs. push ( idx) ;
567
+ }
568
+ '/' if last_char == '*' => {
569
+ last_nested_block_comment_idxs =
570
+ nested_block_comment_open_idxs. pop ( ) . map ( |open_idx| ( open_idx, idx) ) ;
571
+ }
572
+ _ => { }
573
+ } ;
574
+ last_char = c;
575
+ }
576
+ }
577
+
578
+ if let Some ( ( nested_open_idx, nested_close_idx) ) = last_nested_block_comment_idxs {
579
+ err. span_label ( self . mk_sp ( start, start + BytePos ( 2 ) ) , msg)
580
+ . span_label (
581
+ self . mk_sp (
582
+ start + BytePos ( nested_open_idx as u32 - 1 ) ,
583
+ start + BytePos ( nested_open_idx as u32 + 1 ) ,
584
+ ) ,
585
+ "...as last nested comment starts here, maybe you want to close this instead?" ,
586
+ )
587
+ . span_label (
588
+ self . mk_sp (
589
+ start + BytePos ( nested_close_idx as u32 - 1 ) ,
590
+ start + BytePos ( nested_close_idx as u32 + 1 ) ,
591
+ ) ,
592
+ "...and last nested comment terminates here" ,
593
+ ) ;
594
+ }
595
+
596
+ err. emit ( ) ;
597
+ }
598
+
556
599
// RFC 3101 introduced the idea of (reserved) prefixes. As of Rust 2021,
557
600
// using a (unknown) prefix is an error. In earlier editions, however, they
558
601
// only result in a (allowed by default) lint, and are treated as regular
0 commit comments