aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_def/src/body/lower.rs3
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs31
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs4
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs25
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs1
-rw-r--r--crates/ra_syntax/src/ast/generated.rs42
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt21
-rw-r--r--xtask/src/ast_src.rs3
8 files changed, 100 insertions, 30 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 28c570c76..8d4b8b0f0 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -672,8 +672,7 @@ impl ExprCollector<'_> {
672 } 672 }
673 673
674 // FIXME: implement 674 // FIXME: implement
675 ast::Pat::BoxPat(_) => Pat::Missing, 675 ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
676 ast::Pat::RangePat(_) => Pat::Missing,
677 }; 676 };
678 let ptr = AstPtr::new(&pat); 677 let ptr = AstPtr::new(&pat);
679 self.alloc_pat(pattern, Either::Left(ptr)) 678 self.alloc_pat(pattern, Either::Left(ptr))
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs
index eb97288f1..ff4599b71 100644
--- a/crates/ra_hir_ty/src/tests/macros.rs
+++ b/crates/ra_hir_ty/src/tests/macros.rs
@@ -1,8 +1,10 @@
1use super::{infer, type_at, type_at_pos};
2use crate::test_db::TestDB;
3use insta::assert_snapshot; 1use insta::assert_snapshot;
4use ra_db::fixture::WithFixture; 2use ra_db::fixture::WithFixture;
5 3
4use super::{infer, type_at, type_at_pos};
5
6use crate::test_db::TestDB;
7
6#[test] 8#[test]
7fn cfg_impl_def() { 9fn cfg_impl_def() {
8 let (db, pos) = TestDB::with_position( 10 let (db, pos) = TestDB::with_position(
@@ -658,3 +660,28 @@ fn test() {
658 ); 660 );
659 assert_eq!("S", type_at_pos(&db, pos)); 661 assert_eq!("S", type_at_pos(&db, pos));
660} 662}
663
664#[test]
665fn macro_in_arm() {
666 assert_snapshot!(
667 infer(r#"
668macro_rules! unit {
669 () => { () };
670}
671
672fn main() {
673 let x = match () {
674 unit!() => 92u32,
675 };
676}
677"#),
678 @r###"
679 [52; 111) '{ ... }; }': ()
680 [62; 63) 'x': u32
681 [66; 108) 'match ... }': u32
682 [72; 74) '()': ()
683 [85; 92) 'unit!()': ()
684 [96; 101) '92u32': u32
685 "###
686 );
687}
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index 0c170ac5e..c486c0211 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -79,8 +79,6 @@ fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
79} 79}
80 80
81pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) { 81pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
82 // test block_items
83 // fn a() { fn b() {} }
84 let m = p.start(); 82 let m = p.start();
85 // test attr_on_expr_stmt 83 // test attr_on_expr_stmt
86 // fn foo() { 84 // fn foo() {
@@ -97,6 +95,8 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
97 return; 95 return;
98 } 96 }
99 97
98 // test block_items
99 // fn a() { fn b() {} }
100 let m = match items::maybe_item(p, m, items::ItemFlavor::Mod) { 100 let m = match items::maybe_item(p, m, items::ItemFlavor::Mod) {
101 Ok(()) => return, 101 Ok(()) => return,
102 Err(m) => m, 102 Err(m) => m,
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index 3afbaa82b..936d27575 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -70,15 +70,6 @@ fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) {
70 return; 70 return;
71 } 71 }
72 } 72 }
73 // test marco_pat
74 // fn main() {
75 // let m!(x) = 0;
76 // }
77 if lhs.kind() == PATH_PAT && p.at(T![!]) {
78 let m = lhs.undo_completion(p);
79 items::macro_call_after_excl(p);
80 m.complete(p, MACRO_CALL);
81 }
82 } 73 }
83} 74}
84 75
@@ -92,12 +83,12 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
92 IDENT => match p.nth(1) { 83 IDENT => match p.nth(1) {
93 // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro 84 // Checks the token after an IDENT to see if a pattern is a path (Struct { .. }) or macro
94 // (T![x]). 85 // (T![x]).
95 T!['('] | T!['{'] | T![!] => path_pat(p), 86 T!['('] | T!['{'] | T![!] => path_or_macro_pat(p),
96 T![:] if p.nth_at(1, T![::]) => path_pat(p), 87 T![:] if p.nth_at(1, T![::]) => path_or_macro_pat(p),
97 _ => bind_pat(p, true), 88 _ => bind_pat(p, true),
98 }, 89 },
99 90
100 _ if paths::is_use_path_start(p) => path_pat(p), 91 _ if paths::is_use_path_start(p) => path_or_macro_pat(p),
101 _ if is_literal_pat_start(p) => literal_pat(p), 92 _ if is_literal_pat_start(p) => literal_pat(p),
102 93
103 T![.] if p.at(T![..]) => dot_dot_pat(p), 94 T![.] if p.at(T![..]) => dot_dot_pat(p),
@@ -146,7 +137,7 @@ fn literal_pat(p: &mut Parser) -> CompletedMarker {
146// let Bar { .. } = (); 137// let Bar { .. } = ();
147// let Bar(..) = (); 138// let Bar(..) = ();
148// } 139// }
149fn path_pat(p: &mut Parser) -> CompletedMarker { 140fn path_or_macro_pat(p: &mut Parser) -> CompletedMarker {
150 assert!(paths::is_use_path_start(p)); 141 assert!(paths::is_use_path_start(p));
151 let m = p.start(); 142 let m = p.start();
152 paths::expr_path(p); 143 paths::expr_path(p);
@@ -159,6 +150,14 @@ fn path_pat(p: &mut Parser) -> CompletedMarker {
159 record_field_pat_list(p); 150 record_field_pat_list(p);
160 RECORD_PAT 151 RECORD_PAT
161 } 152 }
153 // test marco_pat
154 // fn main() {
155 // let m!(x) = 0;
156 // }
157 T![!] => {
158 items::macro_call_after_excl(p);
159 return m.complete(p, MACRO_CALL).precede(p).complete(p, MACRO_PAT);
160 }
162 _ => PATH_PAT, 161 _ => PATH_PAT,
163 }; 162 };
164 m.complete(p, kind) 163 m.complete(p, kind)
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index dfc30d727..4c16cf1cd 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -167,6 +167,7 @@ pub enum SyntaxKind {
167 SLICE_PAT, 167 SLICE_PAT,
168 RANGE_PAT, 168 RANGE_PAT,
169 LITERAL_PAT, 169 LITERAL_PAT,
170 MACRO_PAT,
170 TUPLE_EXPR, 171 TUPLE_EXPR,
171 ARRAY_EXPR, 172 ARRAY_EXPR,
172 PAREN_EXPR, 173 PAREN_EXPR,
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 7204ca5b1..0c339b987 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -2563,6 +2563,38 @@ impl LiteralPat {
2563 } 2563 }
2564} 2564}
2565#[derive(Debug, Clone, PartialEq, Eq, Hash)] 2565#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2566pub struct MacroPat {
2567 pub(crate) syntax: SyntaxNode,
2568}
2569impl std::fmt::Display for MacroPat {
2570 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
2571 std::fmt::Display::fmt(self.syntax(), f)
2572 }
2573}
2574impl AstNode for MacroPat {
2575 fn can_cast(kind: SyntaxKind) -> bool {
2576 match kind {
2577 MACRO_PAT => true,
2578 _ => false,
2579 }
2580 }
2581 fn cast(syntax: SyntaxNode) -> Option<Self> {
2582 if Self::can_cast(syntax.kind()) {
2583 Some(Self { syntax })
2584 } else {
2585 None
2586 }
2587 }
2588 fn syntax(&self) -> &SyntaxNode {
2589 &self.syntax
2590 }
2591}
2592impl MacroPat {
2593 pub fn macro_call(&self) -> Option<MacroCall> {
2594 AstChildren::new(&self.syntax).next()
2595 }
2596}
2597#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2566pub struct RecordPat { 2598pub struct RecordPat {
2567 pub(crate) syntax: SyntaxNode, 2599 pub(crate) syntax: SyntaxNode,
2568} 2600}
@@ -4600,6 +4632,7 @@ pub enum Pat {
4600 SlicePat(SlicePat), 4632 SlicePat(SlicePat),
4601 RangePat(RangePat), 4633 RangePat(RangePat),
4602 LiteralPat(LiteralPat), 4634 LiteralPat(LiteralPat),
4635 MacroPat(MacroPat),
4603} 4636}
4604impl From<OrPat> for Pat { 4637impl From<OrPat> for Pat {
4605 fn from(node: OrPat) -> Pat { 4638 fn from(node: OrPat) -> Pat {
@@ -4671,6 +4704,11 @@ impl From<LiteralPat> for Pat {
4671 Pat::LiteralPat(node) 4704 Pat::LiteralPat(node)
4672 } 4705 }
4673} 4706}
4707impl From<MacroPat> for Pat {
4708 fn from(node: MacroPat) -> Pat {
4709 Pat::MacroPat(node)
4710 }
4711}
4674impl std::fmt::Display for Pat { 4712impl std::fmt::Display for Pat {
4675 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 4713 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
4676 std::fmt::Display::fmt(self.syntax(), f) 4714 std::fmt::Display::fmt(self.syntax(), f)
@@ -4681,7 +4719,7 @@ impl AstNode for Pat {
4681 match kind { 4719 match kind {
4682 OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT 4720 OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT
4683 | PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT 4721 | PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT
4684 | LITERAL_PAT => true, 4722 | LITERAL_PAT | MACRO_PAT => true,
4685 _ => false, 4723 _ => false,
4686 } 4724 }
4687 } 4725 }
@@ -4701,6 +4739,7 @@ impl AstNode for Pat {
4701 SLICE_PAT => Pat::SlicePat(SlicePat { syntax }), 4739 SLICE_PAT => Pat::SlicePat(SlicePat { syntax }),
4702 RANGE_PAT => Pat::RangePat(RangePat { syntax }), 4740 RANGE_PAT => Pat::RangePat(RangePat { syntax }),
4703 LITERAL_PAT => Pat::LiteralPat(LiteralPat { syntax }), 4741 LITERAL_PAT => Pat::LiteralPat(LiteralPat { syntax }),
4742 MACRO_PAT => Pat::MacroPat(MacroPat { syntax }),
4704 _ => return None, 4743 _ => return None,
4705 }; 4744 };
4706 Some(res) 4745 Some(res)
@@ -4721,6 +4760,7 @@ impl AstNode for Pat {
4721 Pat::SlicePat(it) => &it.syntax, 4760 Pat::SlicePat(it) => &it.syntax,
4722 Pat::RangePat(it) => &it.syntax, 4761 Pat::RangePat(it) => &it.syntax,
4723 Pat::LiteralPat(it) => &it.syntax, 4762 Pat::LiteralPat(it) => &it.syntax,
4763 Pat::MacroPat(it) => &it.syntax,
4724 } 4764 }
4725 } 4765 }
4726} 4766}
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt b/crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt
index b05ccc0ed..36d8f4a5f 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt
@@ -15,16 +15,17 @@ SOURCE_FILE@[0; 33)
15 LET_STMT@[16; 30) 15 LET_STMT@[16; 30)
16 LET_KW@[16; 19) "let" 16 LET_KW@[16; 19) "let"
17 WHITESPACE@[19; 20) " " 17 WHITESPACE@[19; 20) " "
18 MACRO_CALL@[20; 25) 18 MACRO_PAT@[20; 25)
19 PATH@[20; 21) 19 MACRO_CALL@[20; 25)
20 PATH_SEGMENT@[20; 21) 20 PATH@[20; 21)
21 NAME_REF@[20; 21) 21 PATH_SEGMENT@[20; 21)
22 IDENT@[20; 21) "m" 22 NAME_REF@[20; 21)
23 EXCL@[21; 22) "!" 23 IDENT@[20; 21) "m"
24 TOKEN_TREE@[22; 25) 24 EXCL@[21; 22) "!"
25 L_PAREN@[22; 23) "(" 25 TOKEN_TREE@[22; 25)
26 IDENT@[23; 24) "x" 26 L_PAREN@[22; 23) "("
27 R_PAREN@[24; 25) ")" 27 IDENT@[23; 24) "x"
28 R_PAREN@[24; 25) ")"
28 WHITESPACE@[25; 26) " " 29 WHITESPACE@[25; 26) " "
29 EQ@[26; 27) "=" 30 EQ@[26; 27) "="
30 WHITESPACE@[27; 28) " " 31 WHITESPACE@[27; 28) " "
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 99bd60198..d9f51ec39 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -138,6 +138,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
138 "SLICE_PAT", 138 "SLICE_PAT",
139 "RANGE_PAT", 139 "RANGE_PAT",
140 "LITERAL_PAT", 140 "LITERAL_PAT",
141 "MACRO_PAT",
141 // atoms 142 // atoms
142 "TUPLE_EXPR", 143 "TUPLE_EXPR",
143 "ARRAY_EXPR", 144 "ARRAY_EXPR",
@@ -440,6 +441,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
440 struct SlicePat { args: [Pat] } 441 struct SlicePat { args: [Pat] }
441 struct RangePat {} 442 struct RangePat {}
442 struct LiteralPat { Literal } 443 struct LiteralPat { Literal }
444 struct MacroPat { MacroCall }
443 445
444 struct RecordPat { RecordFieldPatList, Path } 446 struct RecordPat { RecordFieldPatList, Path }
445 struct RecordFieldPatList { 447 struct RecordFieldPatList {
@@ -622,6 +624,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
622 SlicePat, 624 SlicePat,
623 RangePat, 625 RangePat,
624 LiteralPat, 626 LiteralPat,
627 MacroPat,
625 } 628 }
626 629
627 enum AttrInput { Literal, TokenTree } 630 enum AttrInput { Literal, TokenTree }