about summary refs log tree commit diff
path: root/compiler/rustc_macros/src/diagnostics/utils.rs
diff options
context:
space:
mode:
authorfinalchild <finalchild2@gmail.com>2022-08-19 02:21:35 +0900
committerfinalchild <finalchild2@gmail.com>2022-08-22 01:11:59 +0900
commit8ed8aac3caa9c943e600392e49702c7215428d23 (patch)
tree629ad871be9de445ae8714d890e8d16b0ddd0ca4 /compiler/rustc_macros/src/diagnostics/utils.rs
parentb28cc097cfbdc9e2f105a7e644389266027bcf7d (diff)
downloadrust-8ed8aac3caa9c943e600392e49702c7215428d23.tar.gz
rust-8ed8aac3caa9c943e600392e49702c7215428d23.zip
Fix `build_format` not unescaping braces properly
Co-authored-by: RanolP <public.ranolp@gmail.com>
Diffstat (limited to 'compiler/rustc_macros/src/diagnostics/utils.rs')
-rw-r--r--compiler/rustc_macros/src/diagnostics/utils.rs59
1 files changed, 32 insertions, 27 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs
index 002abb152f7..ad9ecd39b9e 100644
--- a/compiler/rustc_macros/src/diagnostics/utils.rs
+++ b/compiler/rustc_macros/src/diagnostics/utils.rs
@@ -235,35 +235,40 @@ pub(crate) trait HasFieldMap {
         // the referenced fields. Leaves `it` sitting on the closing brace of the format string, so
         // the next call to `it.next()` retrieves the next character.
         while let Some(c) = it.next() {
-            if c == '{' && *it.peek().unwrap_or(&'\0') != '{' {
-                let mut eat_argument = || -> Option<String> {
-                    let mut result = String::new();
-                    // Format specifiers look like:
-                    //
-                    //   format   := '{' [ argument ] [ ':' format_spec ] '}' .
-                    //
-                    // Therefore, we only need to eat until ':' or '}' to find the argument.
-                    while let Some(c) = it.next() {
-                        result.push(c);
-                        let next = *it.peek().unwrap_or(&'\0');
-                        if next == '}' {
-                            break;
-                        } else if next == ':' {
-                            // Eat the ':' character.
-                            assert_eq!(it.next().unwrap(), ':');
-                            break;
-                        }
-                    }
-                    // Eat until (and including) the matching '}'
-                    while it.next()? != '}' {
-                        continue;
+            if c != '{' {
+                continue;
+            }
+            if *it.peek().unwrap_or(&'\0') == '{' {
+                assert_eq!(it.next().unwrap(), '{');
+                continue;
+            }
+            let mut eat_argument = || -> Option<String> {
+                let mut result = String::new();
+                // Format specifiers look like:
+                //
+                //   format   := '{' [ argument ] [ ':' format_spec ] '}' .
+                //
+                // Therefore, we only need to eat until ':' or '}' to find the argument.
+                while let Some(c) = it.next() {
+                    result.push(c);
+                    let next = *it.peek().unwrap_or(&'\0');
+                    if next == '}' {
+                        break;
+                    } else if next == ':' {
+                        // Eat the ':' character.
+                        assert_eq!(it.next().unwrap(), ':');
+                        break;
                     }
-                    Some(result)
-                };
-
-                if let Some(referenced_field) = eat_argument() {
-                    referenced_fields.insert(referenced_field);
                 }
+                // Eat until (and including) the matching '}'
+                while it.next()? != '}' {
+                    continue;
+                }
+                Some(result)
+            };
+
+            if let Some(referenced_field) = eat_argument() {
+                referenced_fields.insert(referenced_field);
             }
         }