Skip to content

fix: incorrect error message for string literal suffixes #145602

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1561,7 +1561,31 @@ impl<'a> Parser<'a> {
fn parse_expr_lit(&mut self) -> PResult<'a, Box<Expr>> {
let lo = self.token.span;
match self.parse_opt_token_lit() {
Some((token_lit, _)) => {
Some((token_lit, span)) => {
// For raw string literals with suffixes, report the error immediately
// This helps provide better error messages for cases like r#"..."#suffix
if token_lit.suffix.is_some()
&& matches!(token_lit.kind, token::StrRaw(_))
&& ast::LitKind::from_token_lit(token_lit).is_err()
{
if let Err(err) = ast::LitKind::from_token_lit(token_lit) {
let guar = report_lit_error(&self.psess, err, token_lit, span);
let token_lit = token::Lit::new(token::Err(guar), token_lit.symbol, None);
let expr =
self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(token_lit));

// Consume the next token if it looks like another string literal
// This prevents cascading errors when raw strings with invalid suffixes
// are immediately followed by another string
if let TokenKind::Literal(lit) = &self.token.kind {
if matches!(lit.kind, token::LitKind::Str | token::LitKind::StrRaw(_)) {
self.bump();
}
}

return self.maybe_recover_from_bad_qpath(expr);
}
}
let expr = self.mk_expr(lo.to(self.prev_token.span), ExprKind::Lit(token_lit));
self.maybe_recover_from_bad_qpath(expr)
}
Expand Down
12 changes: 6 additions & 6 deletions tests/ui/parser/bad-lit-suffixes.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ error: suffixes on string literals are invalid
LL | "C"suffix
| ^^^^^^^^^ invalid suffix `suffix`

error: suffixes on string literals are invalid
--> $DIR/bad-lit-suffixes.rs:14:5
|
LL | r#""#suffix;
| ^^^^^^^^^^^ invalid suffix `suffix`

error: suffixes on string literals are invalid
--> $DIR/bad-lit-suffixes.rs:30:17
|
Expand Down Expand Up @@ -62,12 +68,6 @@ error: suffixes on byte string literals are invalid
LL | b""suffix;
| ^^^^^^^^^ invalid suffix `suffix`

error: suffixes on string literals are invalid
--> $DIR/bad-lit-suffixes.rs:14:5
|
LL | r#""#suffix;
| ^^^^^^^^^^^ invalid suffix `suffix`

error: suffixes on byte string literals are invalid
--> $DIR/bad-lit-suffixes.rs:15:5
|
Expand Down
7 changes: 7 additions & 0 deletions tests/ui/parser/raw-string-suffix-invalid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Test for issue #144161: Wrong error for string literal suffix when stuck together
// This tests the case where a raw string has an invalid suffix immediately followed by another string

Check failure on line 2 in tests/ui/parser/raw-string-suffix-invalid.rs

View workflow job for this annotation

GitHub Actions / PR - tidy

line longer than 100 chars

Check failure on line 2 in tests/ui/parser/raw-string-suffix-invalid.rs

View workflow job for this annotation

GitHub Actions / PR - aarch64-gnu-llvm-19-2

line longer than 100 chars

fn main() {
let s = r#" \\ "#r"\\ ";
//~^ ERROR suffixes on string literals are invalid
}
8 changes: 8 additions & 0 deletions tests/ui/parser/raw-string-suffix-invalid.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: suffixes on string literals are invalid
--> $DIR/raw-string-suffix-invalid.rs:5:13
|
LL | let s = r#" \ "#r"\ ";
| ^^^^^^^^^^ invalid suffix `r`

error: aborting due to 1 previous error

7 changes: 7 additions & 0 deletions tests/ui/parser/raw-string-suffix-long.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Test for raw string literals with invalid suffixes

fn main() {
// Raw string literal with hash delimiters and suffix
let s2 = r##"test"##suffix;
//~^ ERROR suffixes on string literals are invalid
}
8 changes: 8 additions & 0 deletions tests/ui/parser/raw-string-suffix-long.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: suffixes on string literals are invalid
--> $DIR/raw-string-suffix-long.rs:5:14
|
LL | let s2 = r##"test"##suffix;
| ^^^^^^^^^^^^^^^^^ invalid suffix `suffix`

error: aborting due to 1 previous error

7 changes: 7 additions & 0 deletions tests/ui/parser/raw-string-suffix-word.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Test for raw string literal with word suffix

fn main() {
// Raw string literal with word suffix
let s3 = r#"test"#invalid;
//~^ ERROR suffixes on string literals are invalid
}
8 changes: 8 additions & 0 deletions tests/ui/parser/raw-string-suffix-word.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: suffixes on string literals are invalid
--> $DIR/raw-string-suffix-word.rs:5:14
|
LL | let s3 = r#"test"#invalid;
| ^^^^^^^^^^^^^^^^ invalid suffix `invalid`

error: aborting due to 1 previous error

Loading