From 872bf09381751600de8e58aab65b1d2511c33223 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonasschievink@gmail.com>
Date: Mon, 18 Jan 2021 16:58:43 +0100
Subject: [PATCH] Add `MacroType` syntax

---
 Cargo.lock                                 |  4 +--
 crates/hir_def/src/type_ref.rs             |  2 ++
 crates/parser/src/syntax_kind/generated.rs |  1 +
 crates/syntax/src/ast/generated/nodes.rs   | 33 ++++++++++++++++++++--
 xtask/src/ast_src.rs                       |  1 +
 5 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index ee015eaa3ff..aac473191fe 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1839,9 +1839,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
 
 [[package]]
 name = "ungrammar"
-version = "1.9.0"
+version = "1.9.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b137a875a3b942539dd04bd37d193649f5d67e11407186f5b9d63ae0332b1a93"
+checksum = "58a02e2041a872d56354e843e8e86e6b946fc8e7dc32982fcdc335e29eb4cc8b"
 
 [[package]]
 name = "unicase"
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs
index ae93d0d108d..049b2e462e6 100644
--- a/crates/hir_def/src/type_ref.rs
+++ b/crates/hir_def/src/type_ref.rs
@@ -159,6 +159,8 @@ impl TypeRef {
             ast::Type::DynTraitType(inner) => {
                 TypeRef::DynTrait(type_bounds_from_ast(ctx, inner.type_bound_list()))
             }
+            // FIXME: Macros in type position are not yet supported.
+            ast::Type::MacroType(_) => TypeRef::Error,
         }
     }
 
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs
index 7d53cc4cdc3..bcefd183a1a 100644
--- a/crates/parser/src/syntax_kind/generated.rs
+++ b/crates/parser/src/syntax_kind/generated.rs
@@ -143,6 +143,7 @@ pub enum SyntaxKind {
     MACRO_DEF,
     PAREN_TYPE,
     TUPLE_TYPE,
+    MACRO_TYPE,
     NEVER_TYPE,
     PATH_TYPE,
     PTR_TYPE,
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 6407d7c8517..5baa54a3f84 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -1072,6 +1072,13 @@ impl InferType {
     pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct MacroType {
+    pub(crate) syntax: SyntaxNode,
+}
+impl MacroType {
+    pub fn macro_call(&self) -> Option<MacroCall> { support::child(&self.syntax) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NeverType {
     pub(crate) syntax: SyntaxNode,
 }
@@ -1300,6 +1307,7 @@ pub enum Type {
     ForType(ForType),
     ImplTraitType(ImplTraitType),
     InferType(InferType),
+    MacroType(MacroType),
     NeverType(NeverType),
     ParenType(ParenType),
     PathType(PathType),
@@ -2558,6 +2566,17 @@ impl AstNode for InferType {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for MacroType {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_TYPE }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for NeverType {
     fn can_cast(kind: SyntaxKind) -> bool { kind == NEVER_TYPE }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2889,6 +2908,9 @@ impl From<ImplTraitType> for Type {
 impl From<InferType> for Type {
     fn from(node: InferType) -> Type { Type::InferType(node) }
 }
+impl From<MacroType> for Type {
+    fn from(node: MacroType) -> Type { Type::MacroType(node) }
+}
 impl From<NeverType> for Type {
     fn from(node: NeverType) -> Type { Type::NeverType(node) }
 }
@@ -2914,8 +2936,8 @@ impl AstNode for Type {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
             ARRAY_TYPE | DYN_TRAIT_TYPE | FN_PTR_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | INFER_TYPE
-            | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE | SLICE_TYPE
-            | TUPLE_TYPE => true,
+            | MACRO_TYPE | NEVER_TYPE | PAREN_TYPE | PATH_TYPE | PTR_TYPE | REF_TYPE
+            | SLICE_TYPE | TUPLE_TYPE => true,
             _ => false,
         }
     }
@@ -2927,6 +2949,7 @@ impl AstNode for Type {
             FOR_TYPE => Type::ForType(ForType { syntax }),
             IMPL_TRAIT_TYPE => Type::ImplTraitType(ImplTraitType { syntax }),
             INFER_TYPE => Type::InferType(InferType { syntax }),
+            MACRO_TYPE => Type::MacroType(MacroType { syntax }),
             NEVER_TYPE => Type::NeverType(NeverType { syntax }),
             PAREN_TYPE => Type::ParenType(ParenType { syntax }),
             PATH_TYPE => Type::PathType(PathType { syntax }),
@@ -2946,6 +2969,7 @@ impl AstNode for Type {
             Type::ForType(it) => &it.syntax,
             Type::ImplTraitType(it) => &it.syntax,
             Type::InferType(it) => &it.syntax,
+            Type::MacroType(it) => &it.syntax,
             Type::NeverType(it) => &it.syntax,
             Type::ParenType(it) => &it.syntax,
             Type::PathType(it) => &it.syntax,
@@ -4082,6 +4106,11 @@ impl std::fmt::Display for InferType {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for MacroType {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for NeverType {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 046d68f526f..0fd1d13e635 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -104,6 +104,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
         "MACRO_DEF",
         "PAREN_TYPE",
         "TUPLE_TYPE",
+        "MACRO_TYPE",
         "NEVER_TYPE",
         "PATH_TYPE",
         "PTR_TYPE",