aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-04-03 15:13:15 +0100
committerGitHub <[email protected]>2020-04-03 15:13:15 +0100
commit6a2dd7bafc24ac405aebf29f04120ca071019e92 (patch)
treeac21306c7bf9dc816f4b0e9b50322f57256eddfa /crates/ra_syntax
parent795b8cf9c5a6f3be4117823c896f41d1a4455079 (diff)
parentda8eb29a2f70a58122903bf087bd6c1d0fbd6d3f (diff)
Merge #3836
3836: Macro patterns are not confused with expressions. r=matklad a=matklad We treat macro calls as expressions (there's appropriate Into impl), which causes problem if there's expresison and non-expression macro in the same node (like in the match arm). We fix this problem by nesting macor patterns into another node (the same way we nest path into PathExpr or PathPat). Ideally, we probably should add a similar nesting for macro expressions, but that needs some careful thinking about macros in blocks: `{ am_i_expression!() }`. bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_syntax')
-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
2 files changed, 52 insertions, 11 deletions
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) " "