aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/patterns.rs
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/patterns.rs
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/patterns.rs')
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs25
1 files changed, 12 insertions, 13 deletions
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)