Rollup merge of #140175 - Kivooeo:new-fix-one, r=compiler-errors

`rc""` more clear error message

here is small fix that provides better error message when user is trying to use `rc""` the same way it was made for `rb""`

example of it's work

```rust
  |
2 |     rc"\n";
  |     ^^ unknown prefix
  |
  = note: prefixed identifiers and literals are reserved since Rust 2021
help: use `cr` for a raw C-string
  |
2 -     rc"\n";
2 +     cr"\n";
  |
```

**related issue**
fixes #140170

cc `@cyrgani` (issue author)
This commit is contained in:
Chris Denton 2025-04-23 00:43:08 +00:00 committed by GitHub
commit ecb9775438
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 41 additions and 2 deletions

View file

@ -893,6 +893,7 @@ parse_unknown_prefix = prefix `{$prefix}` is unknown
.label = unknown prefix
.note = prefixed identifiers and literals are reserved since Rust 2021
.suggestion_br = use `br` for a raw byte string
.suggestion_cr = use `cr` for a raw C-string
.suggestion_str = if you meant to write a string literal, use double quotes
.suggestion_whitespace = consider inserting whitespace here

View file

@ -2140,6 +2140,13 @@ pub(crate) enum UnknownPrefixSugg {
style = "verbose"
)]
UseBr(#[primary_span] Span),
#[suggestion(
parse_suggestion_cr,
code = "cr",
applicability = "maybe-incorrect",
style = "verbose"
)]
UseCr(#[primary_span] Span),
#[suggestion(
parse_suggestion_whitespace,
code = " ",

View file

@ -257,7 +257,6 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
let lit_start = start + BytePos(prefix_len);
self.pos = lit_start;
self.cursor = Cursor::new(&str_before[prefix_len as usize..]);
self.report_unknown_prefix(start);
let prefix_span = self.mk_sp(start, lit_start);
return (Token::new(self.ident(start), prefix_span), preceded_by_whitespace);
@ -790,13 +789,14 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
fn report_unknown_prefix(&self, start: BytePos) {
let prefix_span = self.mk_sp(start, self.pos);
let prefix = self.str_from_to(start, self.pos);
let expn_data = prefix_span.ctxt().outer_expn_data();
if expn_data.edition.at_least_rust_2021() {
// In Rust 2021, this is a hard error.
let sugg = if prefix == "rb" {
Some(errors::UnknownPrefixSugg::UseBr(prefix_span))
} else if prefix == "rc" {
Some(errors::UnknownPrefixSugg::UseCr(prefix_span))
} else if expn_data.is_root() {
if self.cursor.first() == '\''
&& let Some(start) = self.last_lifetime

View file

@ -0,0 +1,10 @@
// `rc` and `cr` are easy to confuse; check that we issue a suggestion to help.
//@ edition:2021
fn main() {
rc"abc";
//~^ ERROR: prefix `rc` is unknown
//~| HELP: use `cr` for a raw C-string
//~| ERROR: expected one of
}

View file

@ -0,0 +1,21 @@
error: prefix `rc` is unknown
--> $DIR/raw-c-string-prefix.rs:6:5
|
LL | rc"abc";
| ^^ unknown prefix
|
= note: prefixed identifiers and literals are reserved since Rust 2021
help: use `cr` for a raw C-string
|
LL - rc"abc";
LL + cr"abc";
|
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"abc"`
--> $DIR/raw-c-string-prefix.rs:6:7
|
LL | rc"abc";
| ^^^^^ expected one of 8 possible tokens
error: aborting due to 2 previous errors