about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-08-11 09:58:55 +0200
committerLukas Wirth <lukastw97@gmail.com>2023-08-12 08:27:27 +0200
commit9ac88d8d36b0e53ace1d67e98ec7c38363cd76d8 (patch)
tree2cecc6df0f67415e26c186bf2c0f5c7e9d339a8b
parent05b061205179dab9a5cd94ae66d1c0e9b8febe08 (diff)
downloadrust-9ac88d8d36b0e53ace1d67e98ec7c38363cd76d8.tar.gz
rust-9ac88d8d36b0e53ace1d67e98ec7c38363cd76d8.zip
Fix parser being stuck in eager macro inputs
-rw-r--r--crates/hir-def/src/body/lower.rs3
-rw-r--r--crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs2
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe/regression.rs38
-rw-r--r--crates/parser/src/grammar.rs4
4 files changed, 45 insertions, 2 deletions
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index 3853a6ab3a5..3389fdfb15e 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -505,6 +505,9 @@ impl ExprCollector<'_> {
                 let mut args = Vec::new();
                 let mut arg_types = Vec::new();
                 if let Some(pl) = e.param_list() {
+                    let num_params = pl.params().count();
+                    args.reserve_exact(num_params);
+                    arg_types.reserve_exact(num_params);
                     for param in pl.params() {
                         let pat = this.collect_pat_top(param.pat());
                         let type_ref =
diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index 1250cbb742c..b232651db96 100644
--- a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -238,7 +238,7 @@ fn main() {
     /* error: expected expression */;
     /* error: expected expression, expected COMMA */;
     /* error: expected expression */::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(), ::core::fmt::Display::fmt), ]);
-    /* error: expected expression, expected expression */;
+    /* error: expected expression, expected R_PAREN */;
     ::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(5), ::core::fmt::Display::fmt), ]);
 }
 "##]],
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index b783de4ccc2..97554f93f1c 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -936,3 +936,41 @@ fn main() {
 "##]],
     );
 }
+
+#[test]
+fn eager_regression_154032() {
+    check(
+        r#"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+    format_args /* +errors */ !("{}", &[0 2]);
+}
+
+"#,
+        expect![[r##"
+#[rustc_builtin_macro]
+#[macro_export]
+macro_rules! format_args {}
+
+fn main() {
+    /* error: expected COMMA, expected R_BRACK, expected COMMA, expected COMMA, expected expression, expected R_PAREN *//* parse error: expected COMMA */
+/* parse error: expected R_BRACK */
+/* parse error: expected COMMA */
+/* parse error: expected COMMA */
+/* parse error: expected expression */
+/* parse error: expected R_PAREN */
+/* parse error: expected R_PAREN */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+/* parse error: expected expression, item or let statement */
+::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(&[0 2]), ::core::fmt::Display::fmt), ]);
+}
+
+"##]],
+    );
+}
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 333318f53b7..6a2a9adce15 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -184,7 +184,9 @@ pub(crate) mod entry {
             };
             p.bump_any();
             while !p.at(EOF) && !p.at(closing_paren_kind) {
-                expressions::expr(p);
+                if expressions::expr(p).is_none() {
+                    break;
+                }
                 if !p.at(EOF) && !p.at(closing_paren_kind) {
                     p.expect(T![,]);
                 }