about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2021-03-28 01:33:13 +0900
committerGitHub <noreply@github.com>2021-03-28 01:33:13 +0900
commit973fb4b77feb589cd8fe4c0f5ee2454b246a1532 (patch)
tree63064f4bc45cb025d9ef27074c86a8393b15cdea
parent1f33a6a0daa472260aacd6788a84b27ba2c57f2b (diff)
parent5b9bac2ab62063229c419909f89a41890c57f78f (diff)
downloadrust-973fb4b77feb589cd8fe4c0f5ee2454b246a1532.tar.gz
rust-973fb4b77feb589cd8fe4c0f5ee2454b246a1532.zip
Rollup merge of #83348 - osa1:issue83344, r=jackh726
format macro argument parsing fix

When the character next to `{}` is "shifted" (when mapping a byte index
in the format string to span) we should avoid shifting the span end
index, so first map the index of `}` to span, then bump the span,
instead of first mapping the next byte index to a span (which causes
bumping the end span too much).

Regression test added.

Fixes #83344

---

r? ```@estebank```
-rw-r--r--compiler/rustc_parse_format/src/lib.rs10
-rw-r--r--src/test/ui/macros/issue-83344.rs6
-rw-r--r--src/test/ui/macros/issue-83344.stderr8
-rw-r--r--src/tools/clippy/tests/ui/write_literal_2.stderr5
4 files changed, 23 insertions, 6 deletions
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index a5fdf064e94..50db69f4209 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -213,11 +213,13 @@ impl<'a> Iterator for Parser<'a> {
                         Some(String(self.string(pos + 1)))
                     } else {
                         let arg = self.argument();
-                        if let Some(end) = self.must_consume('}') {
-                            let start = self.to_span_index(pos);
-                            let end = self.to_span_index(end + 1);
+                        if let Some(rbrace_byte_idx) = self.must_consume('}') {
+                            let lbrace_inner_offset = self.to_span_index(pos);
+                            let rbrace_inner_offset = self.to_span_index(rbrace_byte_idx);
                             if self.is_literal {
-                                self.arg_places.push(start.to(end));
+                                self.arg_places.push(
+                                    lbrace_inner_offset.to(InnerOffset(rbrace_inner_offset.0 + 1)),
+                                );
                             }
                         }
                         Some(NextArgument(arg))
diff --git a/src/test/ui/macros/issue-83344.rs b/src/test/ui/macros/issue-83344.rs
new file mode 100644
index 00000000000..c5f7f723587
--- /dev/null
+++ b/src/test/ui/macros/issue-83344.rs
@@ -0,0 +1,6 @@
+// check-fail
+
+fn main() {
+    println!("{}\
+"); //~^ ERROR: 1 positional argument in format string, but no arguments were given
+}
diff --git a/src/test/ui/macros/issue-83344.stderr b/src/test/ui/macros/issue-83344.stderr
new file mode 100644
index 00000000000..1ef70f87a1f
--- /dev/null
+++ b/src/test/ui/macros/issue-83344.stderr
@@ -0,0 +1,8 @@
+error: 1 positional argument in format string, but no arguments were given
+  --> $DIR/issue-83344.rs:4:15
+   |
+LL |     println!("{}\
+   |               ^^
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/write_literal_2.stderr b/src/tools/clippy/tests/ui/write_literal_2.stderr
index 5b488358011..0aa1b55e58c 100644
--- a/src/tools/clippy/tests/ui/write_literal_2.stderr
+++ b/src/tools/clippy/tests/ui/write_literal_2.stderr
@@ -75,8 +75,9 @@ LL |         "1", "2", "3",
    |
 help: try this
    |
-LL |         "some 1{} / {}", "2", "3",
-   |               ^        --
+LL |         "some 1/
+LL |         {} / {}", "2", "3",
+   |
 
 error: literal with an empty format string
   --> $DIR/write_literal_2.rs:25:14