@@ -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 
0 commit comments