@@ -431,10 +431,11 @@ impl<'a> Parser<'a> {
431
431
return Ok ( true ) ;
432
432
} else if self . look_ahead ( 0 , |t| {
433
433
t == & token:: CloseDelim ( token:: Brace )
434
- || (
435
- t. can_begin_expr ( ) && t != & token:: Semi && t != & token:: Pound
436
- // Avoid triggering with too many trailing `#` in raw string.
437
- )
434
+ || ( t. can_begin_expr ( ) && t != & token:: Semi && t != & token:: Pound )
435
+ // Avoid triggering with too many trailing `#` in raw string.
436
+ || ( sm. is_multiline (
437
+ self . prev_token . span . shrink_to_hi ( ) . until ( self . token . span . shrink_to_lo ( ) )
438
+ ) && t == & token:: Pound )
438
439
} ) {
439
440
// Missing semicolon typo. This is triggered if the next token could either start a
440
441
// new statement or is a block close. For example:
@@ -508,7 +509,12 @@ impl<'a> Parser<'a> {
508
509
}
509
510
510
511
if self . check_too_many_raw_str_terminators ( & mut err) {
511
- return Err ( err) ;
512
+ if expected. contains ( & TokenType :: Token ( token:: Semi ) ) && self . eat ( & token:: Semi ) {
513
+ err. emit ( ) ;
514
+ return Ok ( true ) ;
515
+ } else {
516
+ return Err ( err) ;
517
+ }
512
518
}
513
519
514
520
if self . prev_token . span == DUMMY_SP {
@@ -538,22 +544,41 @@ impl<'a> Parser<'a> {
538
544
}
539
545
540
546
fn check_too_many_raw_str_terminators ( & mut self , err : & mut Diagnostic ) -> bool {
547
+ let sm = self . sess . source_map ( ) ;
541
548
match ( & self . prev_token . kind , & self . token . kind ) {
542
549
(
543
550
TokenKind :: Literal ( Lit {
544
551
kind : LitKind :: StrRaw ( n_hashes) | LitKind :: ByteStrRaw ( n_hashes) ,
545
552
..
546
553
} ) ,
547
554
TokenKind :: Pound ,
548
- ) => {
555
+ ) if !sm. is_multiline (
556
+ self . prev_token . span . shrink_to_hi ( ) . until ( self . token . span . shrink_to_lo ( ) ) ,
557
+ ) =>
558
+ {
559
+ let n_hashes: u8 = * n_hashes;
549
560
err. set_primary_message ( "too many `#` when terminating raw string" ) ;
561
+ let str_span = self . prev_token . span ;
562
+ let mut span = self . token . span ;
563
+ let mut count = 0 ;
564
+ while self . token . kind == TokenKind :: Pound
565
+ && !sm. is_multiline ( span. shrink_to_hi ( ) . until ( self . token . span . shrink_to_lo ( ) ) )
566
+ {
567
+ span = span. with_hi ( self . token . span . hi ( ) ) ;
568
+ self . bump ( ) ;
569
+ count += 1 ;
570
+ }
571
+ err. set_span ( span) ;
550
572
err. span_suggestion (
551
- self . token . span ,
552
- "remove the extra `#`" ,
573
+ span,
574
+ & format ! ( "remove the extra `#`{}" , pluralize! ( count ) ) ,
553
575
String :: new ( ) ,
554
576
Applicability :: MachineApplicable ,
555
577
) ;
556
- err. note ( & format ! ( "the raw string started with {n_hashes} `#`s" ) ) ;
578
+ err. span_label (
579
+ str_span,
580
+ & format ! ( "this raw string started with {n_hashes} `#`{}" , pluralize!( n_hashes) ) ,
581
+ ) ;
557
582
true
558
583
}
559
584
_ => false ,
0 commit comments