about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorSasha <sasha.pourcelot@protonmail.com>2020-08-28 23:04:42 +0200
committerSasha <sasha.pourcelot@protonmail.com>2020-08-30 22:09:58 +0200
commitf6d18db402cfebcf5c1bdc8e730f3923b3bb0421 (patch)
tree75a6755f7e97b1a5e7da581a8361ee65193b6b25 /src
parent85fbf49ce0e2274d0acf798f6e703747674feec3 (diff)
downloadrust-f6d18db402cfebcf5c1bdc8e730f3923b3bb0421.tar.gz
rust-f6d18db402cfebcf5c1bdc8e730f3923b3bb0421.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/fmt/incorrect-first-separator.rs22
-rw-r--r--src/test/ui/fmt/incorrect-first-separator.stderr32
2 files changed, 54 insertions, 0 deletions
diff --git a/src/test/ui/fmt/incorrect-first-separator.rs b/src/test/ui/fmt/incorrect-first-separator.rs
new file mode 100644
index 00000000000..0b097fdfab8
--- /dev/null
+++ b/src/test/ui/fmt/incorrect-first-separator.rs
@@ -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}
+}
diff --git a/src/test/ui/fmt/incorrect-first-separator.stderr b/src/test/ui/fmt/incorrect-first-separator.stderr
new file mode 100644
index 00000000000..60d2a82855e
--- /dev/null
+++ b/src/test/ui/fmt/incorrect-first-separator.stderr
@@ -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
+