aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar
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_parser/src/grammar
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_parser/src/grammar')
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs4
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs25
2 files changed, 14 insertions, 15 deletions
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)