Skip to content

Commit 337205e

Browse files
committed
Redo improvement to c-string literal errors in pre-2021
1 parent 3b743f0 commit 337205e

File tree

5 files changed

+141
-46
lines changed

5 files changed

+141
-46
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

+24-7
Original file line numberDiff line numberDiff line change
@@ -640,15 +640,32 @@ impl<'a> Parser<'a> {
640640
}
641641
}
642642

643-
// extra info for `c"str"` before 2021 edition or `c "str"` in all editions
644-
if self.prev_token.is_ident_named(Symbol::intern("c"))
645-
&& let TokenKind::Literal(token::Lit { kind: token::Str | token::StrRaw(..), .. }) =
646-
&self.token.kind
643+
// Extra info for `c"str"` before 2021 edition or `c "str"` in all editions. The heuristic
644+
// 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.
650+
if ((self.prev_token.kind == TokenKind::Ident(sym::c, false)
651+
&& matches!(&self.token.kind, TokenKind::Literal(token::Lit { kind: token::Str, .. })))
652+
|| (self.prev_token.kind == TokenKind::Ident(sym::cr, false)
653+
&& matches!(
654+
&self.token.kind,
655+
TokenKind::Literal(token::Lit { kind: token::Str, .. }) | token::Pound
656+
)))
657+
&& self.prev_token.span.hi() == self.token.span.lo()
658+
&& !self.token.span.at_least_rust_2021()
647659
{
648-
err.note("you may be trying to declare a CStr literal");
649-
err.note("`CStr` literals require edition 2021");
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");
650667
HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
651-
err.note("`c` modifier in CStr literal cannot be followed by whitespace");
668+
return Err(err);
652669
}
653670

654671
// `pub` may be used for an item or `pub(crate)`
+57-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,62 @@
1-
fn main() {
2-
c"str";
1+
macro_rules! construct { ($x:ident) => { $x"str" } }
32
//~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
43
//~| NOTE expected one of 8 possible tokens
5-
//~| NOTE you may be trying to declare a CStr literal
6-
//~| NOTE `CStr` literals require edition 2021
4+
5+
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
10+
//~| HELP pass `--edition 2021` to `rustc`
11+
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
12+
13+
fn check_macro_construct() {
14+
construct!(c); //~ NOTE in this expansion of construct!
15+
}
16+
17+
fn check_macro_contain() {
18+
contain!();
19+
//~^ NOTE in this expansion of contain!
20+
//~| NOTE in this expansion of contain!
21+
//~| NOTE in this expansion of contain!
22+
//~| NOTE in this expansion of contain!
23+
//~| NOTE in this expansion of contain!
24+
}
25+
26+
fn check_basic() {
27+
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
732
//~| HELP pass `--edition 2021` to `rustc`
833
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
9-
//~| NOTE `c` modifier in CStr literal cannot be followed by whitespace
1034
}
35+
36+
fn check_craw() {
37+
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
42+
//~| HELP pass `--edition 2021` to `rustc`
43+
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
44+
}
45+
46+
fn check_craw_hash() {
47+
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
52+
//~| HELP pass `--edition 2021` to `rustc`
53+
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
54+
}
55+
56+
fn check_cstr_space() {
57+
c "str";
58+
//~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
59+
//~| NOTE expected one of 8 possible tokens
60+
}
61+
62+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,67 @@
1-
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
2-
--> $DIR/edition-cstr-2015-2018.rs:2:6
1+
error: found unexpected token `"str"`
2+
--> $DIR/edition-cstr-2015-2018.rs:27:6
33
|
44
LL | c"str";
5-
| ^^^^^ expected one of 8 possible tokens
5+
| ^^^^^ found here
6+
|
7+
= note: you may be trying to declare a c-string literal
8+
= note: c-string literals require edition 2021 or later
9+
= help: pass `--edition 2021` to `rustc`
10+
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
11+
12+
error: found unexpected token `"str"`
13+
--> $DIR/edition-cstr-2015-2018.rs:37:7
14+
|
15+
LL | cr"str";
16+
| ^^^^^ found here
17+
|
18+
= note: you may be trying to declare a c-string literal
19+
= note: c-string literals require edition 2021 or later
20+
= help: pass `--edition 2021` to `rustc`
21+
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
22+
23+
error: found unexpected token `#`
24+
--> $DIR/edition-cstr-2015-2018.rs:47:7
25+
|
26+
LL | cr##"str"##;
27+
| ^ found here
28+
|
29+
= note: you may be trying to declare a c-string literal
30+
= note: c-string literals require edition 2021 or later
31+
= help: pass `--edition 2021` to `rustc`
32+
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
33+
34+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
35+
--> $DIR/edition-cstr-2015-2018.rs:57:7
36+
|
37+
LL | c "str";
38+
| ^^^^^ expected one of 8 possible tokens
39+
40+
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
41+
--> $DIR/edition-cstr-2015-2018.rs:1:44
42+
|
43+
LL | macro_rules! construct { ($x:ident) => { $x"str" } }
44+
| ^^^^^ expected one of 8 possible tokens
45+
...
46+
LL | construct!(c);
47+
| ------------- in this macro invocation
48+
|
49+
= note: this error originates in the macro `construct` (in Nightly builds, run with -Z macro-backtrace for more info)
50+
51+
error: found unexpected token `"str"`
52+
--> $DIR/edition-cstr-2015-2018.rs:5:33
53+
|
54+
LL | macro_rules! contain { () => { c"str" } }
55+
| ^^^^^ found here
56+
...
57+
LL | contain!();
58+
| ---------- in this macro invocation
659
|
7-
= note: you may be trying to declare a CStr literal
8-
= note: `CStr` literals require edition 2021
60+
= note: you may be trying to declare a c-string literal
61+
= note: c-string literals require edition 2021 or later
962
= help: pass `--edition 2021` to `rustc`
1063
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
11-
= note: `c` modifier in CStr literal cannot be followed by whitespace
64+
= note: this error originates in the macro `contain` (in Nightly builds, run with -Z macro-backtrace for more info)
1265

13-
error: aborting due to 1 previous error
66+
error: aborting due to 6 previous errors
1467

tests/ui/editions/edition-cstr-2021.rs

-13
This file was deleted.

tests/ui/editions/edition-cstr-2021.stderr

-14
This file was deleted.

0 commit comments

Comments
 (0)