aboutsummaryrefslogtreecommitdiff
path: root/crates/parser/src/grammar/items.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-12-15 14:45:09 +0000
committerGitHub <[email protected]>2020-12-15 14:45:09 +0000
commitbd4c352831662762ee7a66da77ec9adf623b0a0a (patch)
tree725dfad20b95344ad363b35860cf7e57067bb5e5 /crates/parser/src/grammar/items.rs
parent39aae835fd70d06092c1be1add6eef3984439529 (diff)
parent479babf8740a4d3cf6fc03a5f4a2fca00d387501 (diff)
Merge #6893
6893: Move to upstream `macro_rules!` model r=matklad a=jonas-schievink This changes `macro_rules!` from being treated as a macro invocation to being a first-class item. It also disallows using an additional ident argument for regular macros, so `m! ident(...);` now fails to parse. This matches upstream Rust, and makes the code somewhat simpler by removing repeated "is this a `macro_rules!` call" checks. It will also simplify allowing visibilities on macros, which is currently being proposed in https://github.com/rust-lang/rust/pull/78166. Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/parser/src/grammar/items.rs')
-rw-r--r--crates/parser/src/grammar/items.rs44
1 files changed, 31 insertions, 13 deletions
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs
index ad29b82f7..8999829b4 100644
--- a/crates/parser/src/grammar/items.rs
+++ b/crates/parser/src/grammar/items.rs
@@ -232,6 +232,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> {
232 T![macro] => { 232 T![macro] => {
233 macro_def(p, m); 233 macro_def(p, m);
234 } 234 }
235 IDENT if p.at_contextual_kw("macro_rules") && p.nth(1) == BANG => {
236 macro_rules(p, m);
237 }
235 IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { 238 IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => {
236 // test union_items 239 // test union_items
237 // union Foo {} 240 // union Foo {}
@@ -363,6 +366,34 @@ pub(crate) fn item_list(p: &mut Parser) {
363 m.complete(p, ITEM_LIST); 366 m.complete(p, ITEM_LIST);
364} 367}
365 368
369fn macro_rules(p: &mut Parser, m: Marker) {
370 assert!(p.at_contextual_kw("macro_rules"));
371 p.bump_remap(T![macro_rules]);
372 p.expect(T![!]);
373
374 if p.at(IDENT) {
375 name(p);
376 }
377 // Special-case `macro_rules! try`.
378 // This is a hack until we do proper edition support
379
380 // test try_macro_rules
381 // macro_rules! try { () => {} }
382 if p.at(T![try]) {
383 let m = p.start();
384 p.bump_remap(IDENT);
385 m.complete(p, NAME);
386 }
387
388 match p.current() {
389 T!['{'] => {
390 token_tree(p);
391 }
392 _ => p.error("expected `{`"),
393 }
394 m.complete(p, MACRO_RULES);
395}
396
366// test macro_def 397// test macro_def
367// macro m { ($i:ident) => {} } 398// macro m { ($i:ident) => {} }
368// macro m($i:ident) {} 399// macro m($i:ident) {}
@@ -394,19 +425,6 @@ fn macro_call(p: &mut Parser) -> BlockLike {
394 425
395pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { 426pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike {
396 p.expect(T![!]); 427 p.expect(T![!]);
397 if p.at(IDENT) {
398 name(p);
399 }
400 // Special-case `macro_rules! try`.
401 // This is a hack until we do proper edition support
402
403 // test try_macro_rules
404 // macro_rules! try { () => {} }
405 if p.at(T![try]) {
406 let m = p.start();
407 p.bump_remap(IDENT);
408 m.complete(p, NAME);
409 }
410 428
411 match p.current() { 429 match p.current() {
412 T!['{'] => { 430 T!['{'] => {