From 8a7f0d920ee09a43309188d9ad79d57b2b93e2be Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonas.schievink@ferrous-systems.com>
Date: Mon, 17 Jan 2022 16:52:53 +0100
Subject: [PATCH] Allow macros to expand to or-patterns

---
 crates/hir/src/diagnostics.rs                 |  1 -
 crates/hir/src/lib.rs                         |  7 ++---
 .../src/handlers/missing_match_arms.rs        | 30 +++++++++++++++++++
 crates/parser/src/grammar.rs                  |  2 +-
 4 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index 83c6f2c3b8a..16b9a9ea459 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -164,7 +164,6 @@ pub struct MissingOkOrSomeInTailExpr {
 pub struct MissingMatchArms {
     pub file: HirFileId,
     pub match_expr: AstPtr<ast::Expr>,
-    pub arms: AstPtr<ast::MatchArmList>,
 }
 
 #[derive(Debug)]
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 4b4eb38336c..d3577552361 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -1266,17 +1266,14 @@ impl DefWithBody {
                             if let ast::Expr::MatchExpr(match_expr) =
                                 &source_ptr.value.to_node(&root)
                             {
-                                if let (Some(match_expr), Some(arms)) =
-                                    (match_expr.expr(), match_expr.match_arm_list())
-                                {
+                                if let Some(match_expr) = match_expr.expr() {
                                     acc.push(
                                         MissingMatchArms {
                                             file: source_ptr.file_id,
                                             match_expr: AstPtr::new(&match_expr),
-                                            arms: AstPtr::new(&arms),
                                         }
                                         .into(),
-                                    )
+                                    );
                                 }
                             }
                         }
diff --git a/crates/ide_diagnostics/src/handlers/missing_match_arms.rs b/crates/ide_diagnostics/src/handlers/missing_match_arms.rs
index 6e2764e59ff..6bdcd41a790 100644
--- a/crates/ide_diagnostics/src/handlers/missing_match_arms.rs
+++ b/crates/ide_diagnostics/src/handlers/missing_match_arms.rs
@@ -900,6 +900,36 @@ fn foo() {
         );
     }
 
+    #[test]
+    fn macro_or_pat() {
+        check_diagnostics_no_bails(
+            r#"
+macro_rules! m {
+    () => {
+        Enum::Type1 | Enum::Type2
+    };
+}
+
+enum Enum {
+    Type1,
+    Type2,
+    Type3,
+}
+
+fn f(ty: Enum) {
+    match ty {
+        //^^ error: missing match arm
+        m!() => (),
+    }
+
+    match ty {
+        m!() | Enum::Type3 => ()
+    }
+}
+"#,
+        );
+    }
+
     mod false_negatives {
         //! The implementation of match checking here is a work in progress. As we roll this out, we
         //! prefer false negatives to false positives (ideally there would be no false positives). This
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs
index 0240a6f14f6..4efbf9a606e 100644
--- a/crates/parser/src/grammar.rs
+++ b/crates/parser/src/grammar.rs
@@ -112,7 +112,7 @@ pub(crate) mod entry {
 
         pub(crate) fn pattern(p: &mut Parser) {
             let m = p.start();
-            patterns::pattern_single(p);
+            patterns::pattern_top(p);
             if p.at(EOF) {
                 m.abandon(p);
                 return;