about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-09-24 11:54:29 +0000
committerbors <bors@rust-lang.org>2021-09-24 11:54:29 +0000
commita0648eab3686f100c7ab9b0d38472c740079cce4 (patch)
tree2f0983f6033f3a568ab04ada0bfe7be61fee121d /compiler/rustc_builtin_macros
parent91d8da1f4ba24679e92b7939a26c681a5d2d3548 (diff)
parenta8421cacfec5798f600549508545b85003c2143c (diff)
downloadrust-a0648eab3686f100c7ab9b0d38472c740079cce4.tar.gz
rust-a0648eab3686f100c7ab9b0d38472c740079cce4.zip
Auto merge of #88835 - FabianWolff:issue-88770, r=petrochenkov
Fix error recovery in format macro parsing

Fixes #88770. Basically, the assumption in the following comment is incorrect:
https://github.com/rust-lang/rust/blob/b69fe57261086e70aea9d5b58819a1794bf7c121/compiler/rustc_builtin_macros/src/format.rs#L167-L172

This is only true in the first iteration of the loop, when [`p.clear_expected_tokens()`](https://github.com/rust-lang/rust/blob/b69fe57261086e70aea9d5b58819a1794bf7c121/compiler/rustc_builtin_macros/src/format.rs#L164) is called. In subsequent iterations, `p.expected_tokens` won't be empty, so `p.expect()` won't actually call `unexpected_try_recover()`:
https://github.com/rust-lang/rust/blob/b69fe57261086e70aea9d5b58819a1794bf7c121/compiler/rustc_parse/src/parser/mod.rs#L487-L498

Instead, it will call `expect_one_of()`, which _can_ recover and return `Ok()`. This PR handles this case to fix the ICE in #88770.
Diffstat (limited to 'compiler/rustc_builtin_macros')
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs31
1 files changed, 15 insertions, 16 deletions
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 9b9adc2d7f3..1c9c6834c10 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -164,23 +164,22 @@ fn parse_args<'a>(
                 p.clear_expected_tokens();
             }
 
-            // `Parser::expect` tries to recover using the
-            // `Parser::unexpected_try_recover` function. This function is able
-            // to recover if the expected token is a closing delimiter.
-            //
-            // As `,` is not a closing delimiter, it will always return an `Err`
-            // variant.
-            let mut err = p.expect(&token::Comma).unwrap_err();
-
-            match token::TokenKind::Comma.similar_tokens() {
-                Some(tks) if tks.contains(&p.token.kind) => {
-                    // If a similar token is found, then it may be a typo. We
-                    // consider it as a comma, and continue parsing.
-                    err.emit();
-                    p.bump();
+            match p.expect(&token::Comma) {
+                Err(mut err) => {
+                    match token::TokenKind::Comma.similar_tokens() {
+                        Some(tks) if tks.contains(&p.token.kind) => {
+                            // If a similar token is found, then it may be a typo. We
+                            // consider it as a comma, and continue parsing.
+                            err.emit();
+                            p.bump();
+                        }
+                        // Otherwise stop the parsing and return the error.
+                        _ => return Err(err),
+                    }
+                }
+                Ok(recovered) => {
+                    assert!(recovered);
                 }
-                // Otherwise stop the parsing and return the error.
-                _ => return Err(err),
             }
         }
         first = false;