diff options
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 3 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 31 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 4 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/patterns.rs | 25 | ||||
-rw-r--r-- | crates/ra_parser/src/syntax_kind/generated.rs | 1 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 42 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/inline/ok/0129_marco_pat.txt | 21 | ||||
-rw-r--r-- | xtask/src/ast_src.rs | 3 |
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 @@ | |||
1 | use super::{infer, type_at, type_at_pos}; | ||
2 | use crate::test_db::TestDB; | ||
3 | use insta::assert_snapshot; | 1 | use insta::assert_snapshot; |
4 | use ra_db::fixture::WithFixture; | 2 | use ra_db::fixture::WithFixture; |
5 | 3 | ||
4 | use super::{infer, type_at, type_at_pos}; | ||
5 | |||
6 | use crate::test_db::TestDB; | ||
7 | |||
6 | #[test] | 8 | #[test] |
7 | fn cfg_impl_def() { | 9 | fn 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] | ||
665 | fn macro_in_arm() { | ||
666 | assert_snapshot!( | ||
667 | infer(r#" | ||
668 | macro_rules! unit { | ||
669 | () => { () }; | ||
670 | } | ||
671 | |||
672 | fn 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 | ||
81 | pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) { | 81 | pub(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 | // } |
149 | fn path_pat(p: &mut Parser) -> CompletedMarker { | 140 | fn 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)] |
2566 | pub struct MacroPat { | ||
2567 | pub(crate) syntax: SyntaxNode, | ||
2568 | } | ||
2569 | impl 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 | } | ||
2574 | impl 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 | } | ||
2592 | impl MacroPat { | ||
2593 | pub fn macro_call(&self) -> Option<MacroCall> { | ||
2594 | AstChildren::new(&self.syntax).next() | ||
2595 | } | ||
2596 | } | ||
2597 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
2566 | pub struct RecordPat { | 2598 | pub 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 | } |
4604 | impl From<OrPat> for Pat { | 4637 | impl 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 | } |
4707 | impl From<MacroPat> for Pat { | ||
4708 | fn from(node: MacroPat) -> Pat { | ||
4709 | Pat::MacroPat(node) | ||
4710 | } | ||
4711 | } | ||
4674 | impl std::fmt::Display for Pat { | 4712 | impl 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 } |