Skip to content

Commit

Permalink
Redo improvement to c-string literal errors in pre-2021
Browse files Browse the repository at this point in the history
  • Loading branch information
chfogelman committed Dec 8, 2023
1 parent 3b743f0 commit 337205e
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 46 deletions.
31 changes: 24 additions & 7 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,15 +640,32 @@ impl<'a> Parser<'a> {
}
}

// extra info for `c"str"` before 2021 edition or `c "str"` in all editions
if self.prev_token.is_ident_named(Symbol::intern("c"))
&& let TokenKind::Literal(token::Lit { kind: token::Str | token::StrRaw(..), .. }) =
&self.token.kind
// Extra info for `c"str"` before 2021 edition or `c "str"` in all editions. The heuristic
// here is to identify a cooked, uninterpolated `c` id immediately followed by a string, or
// a cooked, uninterpolated `cr` id immediately followed by a string or a `#`, in an
// edition where c-string literals are not allowed. There is the slight possibility of a
// false positive for a `cr#` that wasn't intended to start a c-string literal, but the
// lexer was greedy and didn't preserve whether the `r#` on its own would have started a
// valid raw string literal.
if ((self.prev_token.kind == TokenKind::Ident(sym::c, false)
&& matches!(&self.token.kind, TokenKind::Literal(token::Lit { kind: token::Str, .. })))
|| (self.prev_token.kind == TokenKind::Ident(sym::cr, false)
&& matches!(
&self.token.kind,
TokenKind::Literal(token::Lit { kind: token::Str, .. }) | token::Pound
)))
&& self.prev_token.span.hi() == self.token.span.lo()
&& !self.token.span.at_least_rust_2021()
{
err.note("you may be trying to declare a CStr literal");
err.note("`CStr` literals require edition 2021");
err.cancel();
let descr = super::token_descr(&self.token);
let mut err =
self.struct_span_err(self.token.span, format!("found unexpected token {descr}"));
err.span_label(self.token.span, "found here".to_owned());
err.note("you may be trying to declare a c-string literal");
err.note("c-string literals require edition 2021 or later");
HelpUseLatestEdition::new().add_to_diagnostic(&mut err);
err.note("`c` modifier in CStr literal cannot be followed by whitespace");
return Err(err);
}

// `pub` may be used for an item or `pub(crate)`
Expand Down
62 changes: 57 additions & 5 deletions tests/ui/editions/edition-cstr-2015-2018.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,62 @@
fn main() {
c"str";
macro_rules! construct { ($x:ident) => { $x"str" } }
//~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
//~| NOTE expected one of 8 possible tokens
//~| NOTE you may be trying to declare a CStr literal
//~| NOTE `CStr` literals require edition 2021

macro_rules! contain { () => { c"str" } }
//~^ ERROR found unexpected token `"str"`
//~| NOTE found here
//~| NOTE you may be trying to declare a c-string literal
//~| NOTE c-string literals require edition 2021 or later
//~| HELP pass `--edition 2021` to `rustc`
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide

fn check_macro_construct() {
construct!(c); //~ NOTE in this expansion of construct!
}

fn check_macro_contain() {
contain!();
//~^ NOTE in this expansion of contain!
//~| NOTE in this expansion of contain!
//~| NOTE in this expansion of contain!
//~| NOTE in this expansion of contain!
//~| NOTE in this expansion of contain!
}

fn check_basic() {
c"str";
//~^ ERROR found unexpected token `"str"`
//~| NOTE found here
//~| NOTE you may be trying to declare a c-string literal
//~| NOTE c-string literals require edition 2021 or later
//~| HELP pass `--edition 2021` to `rustc`
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
//~| NOTE `c` modifier in CStr literal cannot be followed by whitespace
}

fn check_craw() {
cr"str";
//~^ ERROR found unexpected token `"str"`
//~| NOTE found here
//~| NOTE you may be trying to declare a c-string literal
//~| NOTE c-string literals require edition 2021 or later
//~| HELP pass `--edition 2021` to `rustc`
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
}

fn check_craw_hash() {
cr##"str"##;
//~^ ERROR found unexpected token `#`
//~| NOTE found here
//~| NOTE you may be trying to declare a c-string literal
//~| NOTE c-string literals require edition 2021 or later
//~| HELP pass `--edition 2021` to `rustc`
//~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide
}

fn check_cstr_space() {
c "str";
//~^ ERROR expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
//~| NOTE expected one of 8 possible tokens
}

fn main() {}
67 changes: 60 additions & 7 deletions tests/ui/editions/edition-cstr-2015-2018.stderr
Original file line number Diff line number Diff line change
@@ -1,14 +1,67 @@
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
--> $DIR/edition-cstr-2015-2018.rs:2:6
error: found unexpected token `"str"`
--> $DIR/edition-cstr-2015-2018.rs:27:6
|
LL | c"str";
| ^^^^^ expected one of 8 possible tokens
| ^^^^^ found here
|
= note: you may be trying to declare a c-string literal
= note: c-string literals require edition 2021 or later
= help: pass `--edition 2021` to `rustc`
= note: for more on editions, read https://doc.rust-lang.org/edition-guide

error: found unexpected token `"str"`
--> $DIR/edition-cstr-2015-2018.rs:37:7
|
LL | cr"str";
| ^^^^^ found here
|
= note: you may be trying to declare a c-string literal
= note: c-string literals require edition 2021 or later
= help: pass `--edition 2021` to `rustc`
= note: for more on editions, read https://doc.rust-lang.org/edition-guide

error: found unexpected token `#`
--> $DIR/edition-cstr-2015-2018.rs:47:7
|
LL | cr##"str"##;
| ^ found here
|
= note: you may be trying to declare a c-string literal
= note: c-string literals require edition 2021 or later
= help: pass `--edition 2021` to `rustc`
= note: for more on editions, read https://doc.rust-lang.org/edition-guide

error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
--> $DIR/edition-cstr-2015-2018.rs:57:7
|
LL | c "str";
| ^^^^^ expected one of 8 possible tokens

error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"str"`
--> $DIR/edition-cstr-2015-2018.rs:1:44
|
LL | macro_rules! construct { ($x:ident) => { $x"str" } }
| ^^^^^ expected one of 8 possible tokens
...
LL | construct!(c);
| ------------- in this macro invocation
|
= note: this error originates in the macro `construct` (in Nightly builds, run with -Z macro-backtrace for more info)

error: found unexpected token `"str"`
--> $DIR/edition-cstr-2015-2018.rs:5:33
|
LL | macro_rules! contain { () => { c"str" } }
| ^^^^^ found here
...
LL | contain!();
| ---------- in this macro invocation
|
= note: you may be trying to declare a CStr literal
= note: `CStr` literals require edition 2021
= note: you may be trying to declare a c-string literal
= note: c-string literals require edition 2021 or later
= help: pass `--edition 2021` to `rustc`
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
= note: `c` modifier in CStr literal cannot be followed by whitespace
= note: this error originates in the macro `contain` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 1 previous error
error: aborting due to 6 previous errors

13 changes: 0 additions & 13 deletions tests/ui/editions/edition-cstr-2021.rs

This file was deleted.

14 changes: 0 additions & 14 deletions tests/ui/editions/edition-cstr-2021.stderr

This file was deleted.

0 comments on commit 337205e

Please sign in to comment.