Skip to content

Commit c6729bd

Browse files
committed
Improve compiler error for c-strings in pre-2021
1 parent 337205e commit c6729bd

File tree

3 files changed

+40
-46
lines changed

3 files changed

+40
-46
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -640,13 +640,13 @@ impl<'a> Parser<'a> {
640640
}
641641
}
642642

643-
// Extra info for `c"str"` before 2021 edition or `c "str"` in all editions. The heuristic
643+
// Try to detect an intended c-string literal while using a pre-2021 edition. The heuristic
644644
// here is to identify a cooked, uninterpolated `c` id immediately followed by a string, or
645-
// a cooked, uninterpolated `cr` id immediately followed by a string or a `#`, in an
646-
// edition where c-string literals are not allowed. There is the slight possibility of a
647-
// false positive for a `cr#` that wasn't intended to start a c-string literal, but the
648-
// lexer was greedy and didn't preserve whether the `r#` on its own would have started a
649-
// valid raw string literal.
645+
// a cooked, uninterpolated `cr` id immediately followed by a string or a `#`, in an edition
646+
// where c-string literals are not allowed. There is the very slight possibility of a false
647+
// positive for a `cr#` that wasn't intended to start a c-string literal, but identifying
648+
// that in the parser requires unbounded lookahead, so we only add a hint to the existing
649+
// error rather than replacing it entirely.
650650
if ((self.prev_token.kind == TokenKind::Ident(sym::c, false)
651651
&& matches!(&self.token.kind, TokenKind::Literal(token::Lit { kind: token::Str, .. })))
652652
|| (self.prev_token.kind == TokenKind::Ident(sym::cr, false)
@@ -657,15 +657,9 @@ impl<'a> Parser<'a> {
657657
&& self.prev_token.span.hi() == self.token.span.lo()
658658
&& !self.token.span.at_least_rust_2021()
659659
{
660-
err.cancel();
661-
let descr = super::token_descr(&self.token);
662-
let mut err =
663-
self.struct_span_err(self.token.span, format!("found unexpected token {descr}"));
664-
err.span_label(self.token.span, "found here".to_owned());
665-
err.note("you may be trying to declare a c-string literal");
666-
err.note("c-string literals require edition 2021 or later");
660+
err.note("you may be trying to write a c-string literal");
661+
err.note("c-string literals require Rust 2021 or later");
667662
HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
668-
return Err(err);
669663
}
670664

671665
// `pub` may be used for an item or `pub(crate)`

tests/ui/editions/edition-cstr-2015-2018.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ macro_rules! construct { ($x:ident) => { $x"str" } }
33
//~| NOTE expected one of 8 possible tokens
44

55
macro_rules! contain { () => { c"str" } }
6-
//~^ ERROR found unexpected token `"str"`
7-
//~| NOTE found here
8-
//~| NOTE you may be trying to declare a c-string literal
9-
//~| NOTE c-string literals require edition 2021 or later
6+
//~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
7+
//~| NOTE expected one of 8 possible tokens
8+
//~| NOTE you may be trying to write a c-string literal
9+
//~| NOTE c-string literals require Rust 2021 or later
1010
//~| HELP pass `--edition 2021` to `rustc`
1111
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
1212

@@ -25,30 +25,30 @@ fn check_macro_contain() {
2525

2626
fn check_basic() {
2727
c"str";
28-
//~^ ERROR found unexpected token `"str"`
29-
//~| NOTE found here
30-
//~| NOTE you may be trying to declare a c-string literal
31-
//~| NOTE c-string literals require edition 2021 or later
28+
//~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
29+
//~| NOTE expected one of 8 possible tokens
30+
//~| NOTE you may be trying to write a c-string literal
31+
//~| NOTE c-string literals require Rust 2021 or later
3232
//~| HELP pass `--edition 2021` to `rustc`
3333
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
3434
}
3535

3636
fn check_craw() {
3737
cr"str";
38-
//~^ ERROR found unexpected token `"str"`
39-
//~| NOTE found here
40-
//~| NOTE you may be trying to declare a c-string literal
41-
//~| NOTE c-string literals require edition 2021 or later
38+
//~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
39+
//~| NOTE expected one of 8 possible tokens
40+
//~| NOTE you may be trying to write a c-string literal
41+
//~| NOTE c-string literals require Rust 2021 or later
4242
//~| HELP pass `--edition 2021` to `rustc`
4343
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
4444
}
4545

4646
fn check_craw_hash() {
4747
cr##"str"##;
48-
//~^ ERROR found unexpected token `#`
49-
//~| NOTE found here
50-
//~| NOTE you may be trying to declare a c-string literal
51-
//~| NOTE c-string literals require edition 2021 or later
48+
//~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `#`
49+
//~| NOTE expected one of 8 possible tokens
50+
//~| NOTE you may be trying to write a c-string literal
51+
//~| NOTE c-string literals require Rust 2021 or later
5252
//~| HELP pass `--edition 2021` to `rustc`
5353
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
5454
}

tests/ui/editions/edition-cstr-2015-2018.stderr

+16-16
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
error: found unexpected token `"str"`
1+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
22
--> $DIR/edition-cstr-2015-2018.rs:27:6
33
|
44
LL | c"str";
5-
| ^^^^^ found here
5+
| ^^^^^ expected one of 8 possible tokens
66
|
7-
= note: you may be trying to declare a c-string literal
8-
= note: c-string literals require edition 2021 or later
7+
= note: you may be trying to write a c-string literal
8+
= note: c-string literals require Rust 2021 or later
99
= help: pass `--edition 2021` to `rustc`
1010
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
1111

12-
error: found unexpected token `"str"`
12+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
1313
--> $DIR/edition-cstr-2015-2018.rs:37:7
1414
|
1515
LL | cr"str";
16-
| ^^^^^ found here
16+
| ^^^^^ expected one of 8 possible tokens
1717
|
18-
= note: you may be trying to declare a c-string literal
19-
= note: c-string literals require edition 2021 or later
18+
= note: you may be trying to write a c-string literal
19+
= note: c-string literals require Rust 2021 or later
2020
= help: pass `--edition 2021` to `rustc`
2121
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
2222

23-
error: found unexpected token `#`
23+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `#`
2424
--> $DIR/edition-cstr-2015-2018.rs:47:7
2525
|
2626
LL | cr##"str"##;
27-
| ^ found here
27+
| ^ expected one of 8 possible tokens
2828
|
29-
= note: you may be trying to declare a c-string literal
30-
= note: c-string literals require edition 2021 or later
29+
= note: you may be trying to write a c-string literal
30+
= note: c-string literals require Rust 2021 or later
3131
= help: pass `--edition 2021` to `rustc`
3232
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
3333

@@ -48,17 +48,17 @@ LL | construct!(c);
4848
|
4949
= note: this error originates in the macro `construct` (in Nightly builds, run with -Z macro-backtrace for more info)
5050

51-
error: found unexpected token `"str"`
51+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
5252
--> $DIR/edition-cstr-2015-2018.rs:5:33
5353
|
5454
LL | macro_rules! contain { () => { c"str" } }
55-
| ^^^^^ found here
55+
| ^^^^^ expected one of 8 possible tokens
5656
...
5757
LL | contain!();
5858
| ---------- in this macro invocation
5959
|
60-
= note: you may be trying to declare a c-string literal
61-
= note: c-string literals require edition 2021 or later
60+
= note: you may be trying to write a c-string literal
61+
= note: c-string literals require Rust 2021 or later
6262
= help: pass `--edition 2021` to `rustc`
6363
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
6464
= note: this error originates in the macro `contain` (in Nightly builds, run with -Z macro-backtrace for more info)

0 commit comments

Comments
 (0)