about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-06-17 05:54:52 +0900
committerGitHub <noreply@github.com>2021-06-17 05:54:52 +0900
commit4ff55ecf0477034a05bcf4a135e0a25e428cfccb (patch)
tree8dcce4723ea438371afb354fc4fce49aacaec858 /src
parent7030efbb77b15684460f98937f13716d0f2bdea1 (diff)
parent14f3ec2815e9edae3057641ab8f1371cb7cef094 (diff)
downloadrust-4ff55ecf0477034a05bcf4a135e0a25e428cfccb.tar.gz
rust-4ff55ecf0477034a05bcf4a135e0a25e428cfccb.zip
Rollup merge of #86104 - FabianWolff:issue-86085, r=davidtwco
Fix span calculation in format strings

This pull request fixes #86085. The ICE described there is due to an error in the span calculation inside format strings, if the format string is the result of a macro invocation:
```rust
fn main() {
    format!(concat!("abc}"));
}
```
currently produces:
```
error: invalid format string: unmatched `}` found
 --> test.rs:2:17
  |
2 |     format!(concat!("abc}"));
  |                 ^ unmatched `}` in format string
```
which is obviously incorrect. This happens because the span of the entire `concat!()` is combined with the _relative_ location of the unmatched `` `}` `` in the _result_ of the macro invocation (i.e. 4).

In #86085, this has led to a span that starts or ends in the middle of a multibyte character, but the root cause was the same. This pull request fixes the problem.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/fmt/format-concat-span.rs15
-rw-r--r--src/test/ui/fmt/format-concat-span.stderr11
-rw-r--r--src/test/ui/fmt/issue-86085.rs6
-rw-r--r--src/test/ui/fmt/issue-86085.stderr11
4 files changed, 43 insertions, 0 deletions
diff --git a/src/test/ui/fmt/format-concat-span.rs b/src/test/ui/fmt/format-concat-span.rs
new file mode 100644
index 00000000000..ce92df0ad92
--- /dev/null
+++ b/src/test/ui/fmt/format-concat-span.rs
@@ -0,0 +1,15 @@
+// If the format string is another macro invocation, rustc would previously
+// compute nonsensical spans, such as:
+//
+//   error: invalid format string: unmatched `}` found
+//    --> test.rs:2:17
+//     |
+//   2 |     format!(concat!("abc}"));
+//     |                 ^ unmatched `}` in format string
+//
+// This test checks that this behavior has been fixed.
+
+fn main() {
+    format!(concat!("abc}"));
+    //~^ ERROR: invalid format string: unmatched `}` found
+}
diff --git a/src/test/ui/fmt/format-concat-span.stderr b/src/test/ui/fmt/format-concat-span.stderr
new file mode 100644
index 00000000000..da46f40abcb
--- /dev/null
+++ b/src/test/ui/fmt/format-concat-span.stderr
@@ -0,0 +1,11 @@
+error: invalid format string: unmatched `}` found
+  --> $DIR/format-concat-span.rs:13:13
+   |
+LL |     format!(concat!("abc}"));
+   |             ^^^^^^^^^^^^^^^ unmatched `}` in format string
+   |
+   = note: if you intended to print `}`, you can escape it using `}}`
+   = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/fmt/issue-86085.rs b/src/test/ui/fmt/issue-86085.rs
new file mode 100644
index 00000000000..63d42b76969
--- /dev/null
+++ b/src/test/ui/fmt/issue-86085.rs
@@ -0,0 +1,6 @@
+// Tests for an ICE with the fuzzed input below.
+
+fn main ( ) {
+format ! ( concat ! ( r#"lJ𐏿Æ�.𐏿�"# , "r} {}" )     ) ;
+//~^ ERROR: invalid format string: unmatched `}` found
+}
diff --git a/src/test/ui/fmt/issue-86085.stderr b/src/test/ui/fmt/issue-86085.stderr
new file mode 100644
index 00000000000..ee7d8a5cc23
--- /dev/null
+++ b/src/test/ui/fmt/issue-86085.stderr
@@ -0,0 +1,11 @@
+error: invalid format string: unmatched `}` found
+  --> $DIR/issue-86085.rs:4:12
+   |
+LL | format ! ( concat ! ( r#"lJ𐏿Æ�.𐏿�"# , "r} {}" )     ) ;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unmatched `}` in format string
+   |
+   = note: if you intended to print `}`, you can escape it using `}}`
+   = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+