mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-27 07:03:45 +00:00
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.
This commit is contained in:
parent
1e9aa8a96b
commit
3587406967
@ -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,
|
||||
|
@ -1,4 +1,22 @@
|
||||
static s: &'static str =
|
||||
r#"
|
||||
"## //~ too many `#` when terminating raw string
|
||||
r#""## //~ ERROR too many `#` when terminating raw string
|
||||
;
|
||||
|
||||
static s2: &'static str =
|
||||
r#"
|
||||
"#### //~ ERROR too many `#` when terminating raw string
|
||||
;
|
||||
|
||||
const A: &'static str = r"" //~ ERROR expected `;`, found `#`
|
||||
|
||||
// Test
|
||||
#[test]
|
||||
fn test() {}
|
||||
|
||||
const B: &'static str = r""## //~ ERROR too many `#` when terminating raw string
|
||||
|
||||
// Test
|
||||
#[test]
|
||||
fn test2() {}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,10 +1,36 @@
|
||||
error: too many `#` when terminating raw string
|
||||
--> $DIR/raw-str-unbalanced.rs:3:9
|
||||
--> $DIR/raw-str-unbalanced.rs:2:10
|
||||
|
|
||||
LL | "##
|
||||
| ^ help: remove the extra `#`
|
||||
LL | r#""##
|
||||
| -----^ help: remove the extra `#`
|
||||
| |
|
||||
| this raw string started with 1 `#`
|
||||
|
||||
error: too many `#` when terminating raw string
|
||||
--> $DIR/raw-str-unbalanced.rs:7:9
|
||||
|
|
||||
= note: the raw string started with 1 `#`s
|
||||
LL | / r#"
|
||||
LL | | "####
|
||||
| | -^^^ help: remove the extra `#`s
|
||||
| |________|
|
||||
| this raw string started with 1 `#`
|
||||
|
||||
error: aborting due to previous error
|
||||
error: expected `;`, found `#`
|
||||
--> $DIR/raw-str-unbalanced.rs:10:28
|
||||
|
|
||||
LL | const A: &'static str = r""
|
||||
| ^ help: add `;` here
|
||||
...
|
||||
LL | #[test]
|
||||
| - unexpected token
|
||||
|
||||
error: too many `#` when terminating raw string
|
||||
--> $DIR/raw-str-unbalanced.rs:16:28
|
||||
|
|
||||
LL | const B: &'static str = r""##
|
||||
| ---^^ help: remove the extra `#`s
|
||||
| |
|
||||
| this raw string started with 0 `#`s
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user