Use string literal directly when available in format

Previous implementation used the `Parser::parse_expr` function in order
to extract the format expression. If the first comma following the
format expression was mistakenly replaced with a dot, then the next
format expression was eaten by the function, because it looked as a
syntactically valid expression, which resulted in incorrectly spanned
error messages.

The way the format expression is exctracted is changed: we first look at
the first available token in the first argument supplied to the
`format!` macro call. If it is a string literal, then it is promoted as
a format expression immediatly, otherwise we fall back to the original
`parse_expr`-related method.

This allows us to ensure that the parser won't consume too much tokens
when a typo is made.

A test has been created so that it is ensured that the issue is properly
fixed.
This commit is contained in:
Sasha 2020-08-28 23:04:42 +02:00
parent 85fbf49ce0
commit f6d18db402
4 changed files with 75 additions and 2 deletions

View file

@ -0,0 +1,22 @@
// Allows to track issue #75492:
// https://github.com/rust-lang/rust/issues/75492
use std::iter;
fn main() {
format!("A number: {}". iter::once(42).next().unwrap());
//~^ ERROR expected token: `,`
// Other kind of types are also checked:
format!("A number: {}" / iter::once(42).next().unwrap());
//~^ ERROR expected token: `,`
format!("A number: {}"; iter::once(42).next().unwrap());
//~^ ERROR expected token: `,`
// Note: this character is an COMBINING COMMA BELOW unicode char
format!("A number: {}" ̦ iter::once(42).next().unwrap());
//~^ ERROR expected token: `,`
//~^^ ERROR unknown start of token: \u{326}
}

View file

@ -0,0 +1,32 @@
error: unknown start of token: \u{326}
--> $DIR/incorrect-first-separator.rs:19:28
|
LL | format!("A number: {}" ̦ iter::once(42).next().unwrap());
| ^
error: expected token: `,`
--> $DIR/incorrect-first-separator.rs:7:27
|
LL | format!("A number: {}". iter::once(42).next().unwrap());
| ^ expected `,`
error: expected token: `,`
--> $DIR/incorrect-first-separator.rs:12:28
|
LL | format!("A number: {}" / iter::once(42).next().unwrap());
| ^ expected `,`
error: expected token: `,`
--> $DIR/incorrect-first-separator.rs:15:27
|
LL | format!("A number: {}"; iter::once(42).next().unwrap());
| ^ expected `,`
error: expected token: `,`
--> $DIR/incorrect-first-separator.rs:19:30
|
LL | format!("A number: {}" ̦ iter::once(42).next().unwrap());
| ^^^^ expected `,`
error: aborting due to 5 previous errors