about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJosh Triplett <josh@joshtriplett.org>2025-07-03 20:53:10 -0700
committerJosh Triplett <josh@joshtriplett.org>2025-07-03 20:56:05 -0700
commit0403990000438742065e54c4cae9bb1afb0e6038 (patch)
treeda043936b0faba1c55f091fb4ec4e3b894b23bc5
parentda58c051315268a197ce280f6ba07bbd03c66535 (diff)
downloadrust-0403990000438742065e54c4cae9bb1afb0e6038.tar.gz
rust-0403990000438742065e54c4cae9bb1afb0e6038.zip
mbe: Gracefully handle macro rules that end after `=>`
Add a test for various cases of invalid macro definitions.

Closes: https://github.com/rust-lang/rust/issues/143351
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs9
-rw-r--r--tests/ui/parser/macro/bad-macro-definition.rs22
-rw-r--r--tests/ui/parser/macro/bad-macro-definition.stderr56
3 files changed, 87 insertions, 0 deletions
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index dad2fd99ef2..2ffd4e3cf28 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -411,6 +411,15 @@ pub fn compile_declarative_macro(
         if let Err(e) = p.expect(exp!(FatArrow)) {
             return dummy_syn_ext(e.emit());
         }
+        if p.token == token::Eof {
+            let err_sp = p.token.span.shrink_to_hi();
+            let guar = sess
+                .dcx()
+                .struct_span_err(err_sp, "macro definition ended unexpectedly")
+                .with_span_label(err_sp, "expected right-hand side of macro rule")
+                .emit();
+            return dummy_syn_ext(guar);
+        }
         let rhs_tt = p.parse_token_tree();
         let rhs_tt = mbe::quoted::parse(
             &TokenStream::new(vec![rhs_tt]),
diff --git a/tests/ui/parser/macro/bad-macro-definition.rs b/tests/ui/parser/macro/bad-macro-definition.rs
new file mode 100644
index 00000000000..3c5c93ea3b3
--- /dev/null
+++ b/tests/ui/parser/macro/bad-macro-definition.rs
@@ -0,0 +1,22 @@
+#![crate_type = "lib"]
+
+macro_rules! a { {} => }
+//~^ ERROR: macro definition ended unexpectedly
+
+macro_rules! b { 0 => }
+//~^ ERROR: macro definition ended unexpectedly
+//~| ERROR: invalid macro matcher
+
+macro_rules! c { x => }
+//~^ ERROR: macro definition ended unexpectedly
+//~| ERROR: invalid macro matcher
+
+macro_rules! d { _ => }
+//~^ ERROR: macro definition ended unexpectedly
+//~| ERROR: invalid macro matcher
+
+macro_rules! e { {} }
+//~^ ERROR: expected `=>`, found end of macro arguments
+
+macro_rules! f {}
+//~^ ERROR: macros must contain at least one rule
diff --git a/tests/ui/parser/macro/bad-macro-definition.stderr b/tests/ui/parser/macro/bad-macro-definition.stderr
new file mode 100644
index 00000000000..de6d9d6a38b
--- /dev/null
+++ b/tests/ui/parser/macro/bad-macro-definition.stderr
@@ -0,0 +1,56 @@
+error: macro definition ended unexpectedly
+  --> $DIR/bad-macro-definition.rs:3:23
+   |
+LL | macro_rules! a { {} => }
+   |                       ^ expected right-hand side of macro rule
+
+error: invalid macro matcher; matchers must be contained in balanced delimiters
+  --> $DIR/bad-macro-definition.rs:6:18
+   |
+LL | macro_rules! b { 0 => }
+   |                  ^
+
+error: macro definition ended unexpectedly
+  --> $DIR/bad-macro-definition.rs:6:22
+   |
+LL | macro_rules! b { 0 => }
+   |                      ^ expected right-hand side of macro rule
+
+error: invalid macro matcher; matchers must be contained in balanced delimiters
+  --> $DIR/bad-macro-definition.rs:10:18
+   |
+LL | macro_rules! c { x => }
+   |                  ^
+
+error: macro definition ended unexpectedly
+  --> $DIR/bad-macro-definition.rs:10:22
+   |
+LL | macro_rules! c { x => }
+   |                      ^ expected right-hand side of macro rule
+
+error: invalid macro matcher; matchers must be contained in balanced delimiters
+  --> $DIR/bad-macro-definition.rs:14:18
+   |
+LL | macro_rules! d { _ => }
+   |                  ^
+
+error: macro definition ended unexpectedly
+  --> $DIR/bad-macro-definition.rs:14:22
+   |
+LL | macro_rules! d { _ => }
+   |                      ^ expected right-hand side of macro rule
+
+error: expected `=>`, found end of macro arguments
+  --> $DIR/bad-macro-definition.rs:18:20
+   |
+LL | macro_rules! e { {} }
+   |                    ^ expected `=>`
+
+error: macros must contain at least one rule
+  --> $DIR/bad-macro-definition.rs:21:1
+   |
+LL | macro_rules! f {}
+   | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
+