diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-04-26 01:21:22 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-26 01:21:22 +0200 |
| commit | 77031f3d99f5568ae8ce4aef0e22cff631cf1993 (patch) | |
| tree | bb2fed44bb518257ec38d63716390faa703ffa29 /compiler/rustc_parse/src/parser | |
| parent | 2381897f274b99364b70b85a9b57d1d6e9f103ee (diff) | |
| parent | 35874069679cf394e8a93bd5764ce13f9696096b (diff) | |
| download | rust-77031f3d99f5568ae8ce4aef0e22cff631cf1993.tar.gz rust-77031f3d99f5568ae8ce4aef0e22cff631cf1993.zip | |
Rollup merge of #96355 - estebank:issue-95030, r=compiler-errors
Better handle too many `#` recovery in raw str Point at all the unnecessary trailing `#`. Better handle interaction with outer attributes when `;` is missing. Fix #95030.
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index ed264045170..acc0d7a6ee0 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -431,10 +431,11 @@ impl<'a> Parser<'a> { return Ok(true); } else if self.look_ahead(0, |t| { t == &token::CloseDelim(token::Brace) - || ( - t.can_begin_expr() && t != &token::Semi && t != &token::Pound - // Avoid triggering with too many trailing `#` in raw string. - ) + || (t.can_begin_expr() && t != &token::Semi && t != &token::Pound) + // Avoid triggering with too many trailing `#` in raw string. + || (sm.is_multiline( + self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()) + ) && t == &token::Pound) }) { // Missing semicolon typo. This is triggered if the next token could either start a // new statement or is a block close. For example: @@ -508,7 +509,12 @@ impl<'a> Parser<'a> { } if self.check_too_many_raw_str_terminators(&mut err) { - return Err(err); + if expected.contains(&TokenType::Token(token::Semi)) && self.eat(&token::Semi) { + err.emit(); + return Ok(true); + } else { + return Err(err); + } } if self.prev_token.span == DUMMY_SP { @@ -538,6 +544,7 @@ impl<'a> Parser<'a> { } fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool { + let sm = self.sess.source_map(); match (&self.prev_token.kind, &self.token.kind) { ( TokenKind::Literal(Lit { @@ -545,15 +552,33 @@ impl<'a> Parser<'a> { .. }), TokenKind::Pound, - ) => { + ) if !sm.is_multiline( + self.prev_token.span.shrink_to_hi().until(self.token.span.shrink_to_lo()), + ) => + { + let n_hashes: u8 = *n_hashes; err.set_primary_message("too many `#` when terminating raw string"); + let str_span = self.prev_token.span; + let mut span = self.token.span; + let mut count = 0; + while self.token.kind == TokenKind::Pound + && !sm.is_multiline(span.shrink_to_hi().until(self.token.span.shrink_to_lo())) + { + span = span.with_hi(self.token.span.hi()); + self.bump(); + count += 1; + } + err.set_span(span); err.span_suggestion( - self.token.span, - "remove the extra `#`", + span, + &format!("remove the extra `#`{}", pluralize!(count)), String::new(), Applicability::MachineApplicable, ); - err.note(&format!("the raw string started with {n_hashes} `#`s")); + err.span_label( + str_span, + &format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)), + ); true } _ => false, |
