aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs10
-rw-r--r--crates/ra_parser/src/grammar/items.rs30
-rw-r--r--crates/ra_parser/src/grammar/patterns.rs2
-rw-r--r--crates/ra_parser/src/grammar/type_params.rs11
4 files changed, 49 insertions, 4 deletions
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index f06191963..4ac1d6334 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -43,6 +43,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
43 T!['('], 43 T!['('],
44 T!['{'], 44 T!['{'],
45 T!['['], 45 T!['['],
46 L_DOLLAR,
46 T![|], 47 T![|],
47 T![move], 48 T![move],
48 T![box], 49 T![box],
@@ -248,7 +249,12 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
248 p.error("expected `{`"); 249 p.error("expected `{`");
249 } 250 }
250 } 251 }
251 expr(p); 252
253 if p.at_ts(EXPR_FIRST) {
254 expr(p);
255 } else {
256 p.error("expected expression");
257 }
252 m.complete(p, LAMBDA_EXPR) 258 m.complete(p, LAMBDA_EXPR)
253} 259}
254 260
@@ -438,7 +444,7 @@ fn match_arm(p: &mut Parser) -> BlockLike {
438 // } 444 // }
439 attributes::outer_attributes(p); 445 attributes::outer_attributes(p);
440 446
441 patterns::pattern_list_r(p, TokenSet::empty()); 447 patterns::pattern_list_r(p, TokenSet::EMPTY);
442 if p.at(T![if]) { 448 if p.at(T![if]) {
443 match_guard(p); 449 match_guard(p);
444 } 450 }
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 370990e21..6e23d9b72 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -33,7 +33,7 @@ pub(super) enum ItemFlavor {
33 33
34pub(super) const ITEM_RECOVERY_SET: TokenSet = token_set![ 34pub(super) const ITEM_RECOVERY_SET: TokenSet = token_set![
35 FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW, MOD_KW, PUB_KW, 35 FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW, MOD_KW, PUB_KW,
36 CRATE_KW, USE_KW 36 CRATE_KW, USE_KW, MACRO_KW
37]; 37];
38 38
39pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) { 39pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) {
@@ -249,6 +249,11 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
249 // } 249 // }
250 adt::struct_def(p, m); 250 adt::struct_def(p, m);
251 } 251 }
252 // test pub_macro_def
253 // pub macro m($:ident) {}
254 T![macro] => {
255 macro_def(p, m);
256 }
252 IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { 257 IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => {
253 // test union_items 258 // test union_items
254 // union Foo {} 259 // union Foo {}
@@ -379,6 +384,29 @@ pub(crate) fn mod_item_list(p: &mut Parser) {
379 m.complete(p, ITEM_LIST); 384 m.complete(p, ITEM_LIST);
380} 385}
381 386
387// test macro_def
388// macro m { ($i:ident) => {} }
389// macro m($i:ident) {}
390fn macro_def(p: &mut Parser, m: Marker) {
391 p.expect(T![macro]);
392 name_r(p, ITEM_RECOVERY_SET);
393 if p.at(T!['{']) {
394 token_tree(p);
395 } else if !p.at(T!['(']) {
396 p.error("unmatched `(`");
397 } else {
398 let m = p.start();
399 token_tree(p);
400 match p.current() {
401 T!['{'] | T!['['] | T!['('] => token_tree(p),
402 _ => p.error("expected `{`, `[`, `(`"),
403 }
404 m.complete(p, TOKEN_TREE);
405 }
406
407 m.complete(p, MACRO_DEF);
408}
409
382fn macro_call(p: &mut Parser) -> BlockLike { 410fn macro_call(p: &mut Parser) -> BlockLike {
383 assert!(paths::is_use_path_start(p)); 411 assert!(paths::is_use_path_start(p));
384 paths::use_path(p); 412 paths::use_path(p);
diff --git a/crates/ra_parser/src/grammar/patterns.rs b/crates/ra_parser/src/grammar/patterns.rs
index f5d12278c..422a4e3dc 100644
--- a/crates/ra_parser/src/grammar/patterns.rs
+++ b/crates/ra_parser/src/grammar/patterns.rs
@@ -50,7 +50,7 @@ pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) {
50 // let m!(x) = 0; 50 // let m!(x) = 0;
51 // } 51 // }
52 if lhs.kind() == PATH_PAT && p.at(T![!]) { 52 if lhs.kind() == PATH_PAT && p.at(T![!]) {
53 let m = lhs.precede(p); 53 let m = lhs.undo_completion(p);
54 items::macro_call_after_excl(p); 54 items::macro_call_after_excl(p);
55 m.complete(p, MACRO_CALL); 55 m.complete(p, MACRO_CALL);
56 } 56 }
diff --git a/crates/ra_parser/src/grammar/type_params.rs b/crates/ra_parser/src/grammar/type_params.rs
index 34406b5bd..50e4900c3 100644
--- a/crates/ra_parser/src/grammar/type_params.rs
+++ b/crates/ra_parser/src/grammar/type_params.rs
@@ -25,6 +25,7 @@ fn type_param_list(p: &mut Parser) {
25 match p.current() { 25 match p.current() {
26 LIFETIME => lifetime_param(p, m), 26 LIFETIME => lifetime_param(p, m),
27 IDENT => type_param(p, m), 27 IDENT => type_param(p, m),
28 CONST_KW => type_const_param(p, m),
28 _ => { 29 _ => {
29 m.abandon(p); 30 m.abandon(p);
30 p.err_and_bump("expected type parameter") 31 p.err_and_bump("expected type parameter")
@@ -62,6 +63,16 @@ fn type_param(p: &mut Parser, m: Marker) {
62 m.complete(p, TYPE_PARAM); 63 m.complete(p, TYPE_PARAM);
63} 64}
64 65
66// test const_param
67// struct S<const N: u32>;
68fn type_const_param(p: &mut Parser, m: Marker) {
69 assert!(p.at(CONST_KW));
70 p.bump(T![const]);
71 name(p);
72 types::ascription(p);
73 m.complete(p, CONST_PARAM);
74}
75
65// test type_param_bounds 76// test type_param_bounds
66// struct S<T: 'a + ?Sized + (Copy)>; 77// struct S<T: 'a + ?Sized + (Copy)>;
67pub(super) fn bounds(p: &mut Parser) { 78pub(super) fn bounds(p: &mut Parser) {