Merge commit 'a911652360' into sync-from-ra

This commit is contained in:
Laurențiu Nicola 2024-01-21 16:53:06 +02:00
parent 0661390ad4
commit e4866b6ddb
315 changed files with 7088 additions and 4415 deletions

View file

@ -58,14 +58,21 @@ pub(super) fn item_or_macro(p: &mut Parser<'_>, stop_on_r_curly: bool) {
Err(m) => m,
};
if paths::is_use_path_start(p) {
match macro_call(p) {
BlockLike::Block => (),
BlockLike::NotBlock => {
p.expect(T![;]);
}
}
m.complete(p, MACRO_CALL);
// test macro_rules_as_macro_name
// macro_rules! {}
// macro_rules! ();
// macro_rules! [];
// fn main() {
// let foo = macro_rules!();
// }
// test_err macro_rules_as_macro_name
// macro_rules! {};
// macro_rules! ()
// macro_rules! []
let no_ident = p.at_contextual_kw(T![macro_rules]) && p.nth_at(1, BANG) && !p.nth_at(2, IDENT);
if paths::is_use_path_start(p) || no_ident {
macro_call(p, m);
return;
}
@ -228,7 +235,15 @@ fn opt_item_without_modifiers(p: &mut Parser<'_>, m: Marker) -> Result<(), Marke
IDENT if p.at_contextual_kw(T![union]) && p.nth(1) == IDENT => adt::union(p, m),
T![macro] => macro_def(p, m),
IDENT if p.at_contextual_kw(T![macro_rules]) && p.nth(1) == BANG => macro_rules(p, m),
// check if current token is "macro_rules" followed by "!" followed by an identifier or "try"
// try is keyword since the 2018 edition and the parser is not edition aware (yet!)
IDENT
if p.at_contextual_kw(T![macro_rules])
&& p.nth_at(1, BANG)
&& (p.nth_at(2, IDENT) || p.nth_at(2, T![try])) =>
{
macro_rules(p, m)
}
T![const] if (la == IDENT || la == T![_] || la == T![mut]) => consts::konst(p, m),
T![static] if (la == IDENT || la == T![_] || la == T![mut]) => consts::static_(p, m),
@ -414,10 +429,16 @@ fn fn_(p: &mut Parser<'_>, m: Marker) {
m.complete(p, FN);
}
fn macro_call(p: &mut Parser<'_>) -> BlockLike {
fn macro_call(p: &mut Parser<'_>, m: Marker) {
assert!(paths::is_use_path_start(p));
paths::use_path(p);
macro_call_after_excl(p)
match macro_call_after_excl(p) {
BlockLike::Block => (),
BlockLike::NotBlock => {
p.expect(T![;]);
}
}
m.complete(p, MACRO_CALL);
}
pub(super) fn macro_call_after_excl(p: &mut Parser<'_>) -> BlockLike {

View file

@ -11,7 +11,7 @@ pub(super) fn use_(p: &mut Parser<'_>, m: Marker) {
// test use_tree
// use outer::tree::{inner::tree};
fn use_tree(p: &mut Parser<'_>, top_level: bool) {
fn use_tree(p: &mut Parser<'_>, top_level: bool) -> bool {
let m = p.start();
match p.current() {
// test use_tree_star
@ -70,24 +70,32 @@ fn use_tree(p: &mut Parser<'_>, top_level: bool) {
// main balanced `{}`
p.err_and_bump(msg);
}
return;
return false;
}
}
m.complete(p, USE_TREE);
true
}
pub(super) const USE_TREE_LIST_RECOVERY_SET: TokenSet =
TokenSet::new(&[T![;], T![,], T![.], T![ident]]).union(ITEM_RECOVERY_SET);
pub(super) const USE_TREE_LIST_FIRST_SET: TokenSet = TokenSet::new(&[T!['{'], T![ident]]);
// test use_tree_list
// use {a, b, c};
pub(crate) fn use_tree_list(p: &mut Parser<'_>) {
assert!(p.at(T!['{']));
let m = p.start();
p.bump(T!['{']);
while !p.at(EOF) && !p.at(T!['}']) {
use_tree(p, false);
if !p.at(T!['}']) {
p.expect(T![,]);
}
}
p.expect(T!['}']);
// test_err use_tree_list_err_recovery
// use {a;
// use b;
// struct T;
// fn test() {}
delimited(p, T!['{'], T!['}'], T![,], USE_TREE_LIST_FIRST_SET, |p: &mut Parser<'_>| {
use_tree(p, false) || p.at_ts(USE_TREE_LIST_RECOVERY_SET)
});
m.complete(p, USE_TREE_LIST);
}

View file

@ -22,7 +22,7 @@ fn sourcegen_parser_tests() {
}
// ok is never actually read, but it needs to be specified to create a Test in existing_tests
let existing = existing_tests(&tests_dir, true);
for t in existing.keys().filter(|&t| !tests.contains_key(t)) {
if let Some(t) = existing.keys().find(|&t| !tests.contains_key(t)) {
panic!("Test is deleted: {t}");
}

View file

@ -20,32 +20,21 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Error"
ERROR
SEMICOLON ";"
WHITESPACE "\n"
ERROR
USE_KW "use"
WHITESPACE " "
USE_TREE
PATH
PATH
PATH_SEGMENT
NAME_REF
IDENT "std"
COLON2 "::"
PATH_SEGMENT
NAME_REF
IDENT "io"
ERROR
SEMICOLON ";"
SEMICOLON ";"
WHITESPACE "\n"
error 22: expected COMMA
error 22: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
error 23: expected COMMA
error 24: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
error 27: expected COMMA
error 35: expected COMMA
error 35: expected one of `*`, `::`, `{`, `self`, `super` or an identifier
error 36: expected COMMA
error 36: expected R_CURLY
error 36: expected SEMICOLON
USE
USE_KW "use"
WHITESPACE " "
USE_TREE
PATH
PATH
PATH_SEGMENT
NAME_REF
IDENT "std"
COLON2 "::"
PATH_SEGMENT
NAME_REF
IDENT "io"
SEMICOLON ";"
WHITESPACE "\n"
error 22: expected R_CURLY

View file

@ -0,0 +1,39 @@
SOURCE_FILE
MACRO_CALL
PATH
PATH_SEGMENT
NAME_REF
IDENT "macro_rules"
BANG "!"
WHITESPACE " "
TOKEN_TREE
L_CURLY "{"
R_CURLY "}"
ERROR
SEMICOLON ";"
WHITESPACE "\n"
MACRO_CALL
PATH
PATH_SEGMENT
NAME_REF
IDENT "macro_rules"
BANG "!"
WHITESPACE " "
TOKEN_TREE
L_PAREN "("
R_PAREN ")"
WHITESPACE "\n"
MACRO_CALL
PATH
PATH_SEGMENT
NAME_REF
IDENT "macro_rules"
BANG "!"
WHITESPACE " "
TOKEN_TREE
L_BRACK "["
R_BRACK "]"
WHITESPACE "\n"
error 15: expected an item
error 32: expected SEMICOLON
error 48: expected SEMICOLON

View file

@ -0,0 +1,3 @@
macro_rules! {};
macro_rules! ()
macro_rules! []

View file

@ -0,0 +1,46 @@
SOURCE_FILE
USE
USE_KW "use"
WHITESPACE " "
USE_TREE
USE_TREE_LIST
L_CURLY "{"
USE_TREE
PATH
PATH_SEGMENT
NAME_REF
IDENT "a"
SEMICOLON ";"
WHITESPACE "\n"
USE
USE_KW "use"
WHITESPACE " "
USE_TREE
PATH
PATH_SEGMENT
NAME_REF
IDENT "b"
SEMICOLON ";"
WHITESPACE "\n"
STRUCT
STRUCT_KW "struct"
WHITESPACE " "
NAME
IDENT "T"
SEMICOLON ";"
WHITESPACE "\n"
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "test"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
R_CURLY "}"
WHITESPACE "\n"
error 6: expected R_CURLY

View file

@ -0,0 +1,4 @@
use {a;
use b;
struct T;
fn test() {}

View file

@ -0,0 +1,72 @@
SOURCE_FILE
MACRO_CALL
PATH
PATH_SEGMENT
NAME_REF
IDENT "macro_rules"
BANG "!"
WHITESPACE " "
TOKEN_TREE
L_CURLY "{"
R_CURLY "}"
WHITESPACE "\n"
MACRO_CALL
PATH
PATH_SEGMENT
NAME_REF
IDENT "macro_rules"
BANG "!"
WHITESPACE " "
TOKEN_TREE
L_PAREN "("
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n"
MACRO_CALL
PATH
PATH_SEGMENT
NAME_REF
IDENT "macro_rules"
BANG "!"
WHITESPACE " "
TOKEN_TREE
L_BRACK "["
R_BRACK "]"
SEMICOLON ";"
WHITESPACE "\n"
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "main"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE "\n "
LET_STMT
LET_KW "let"
WHITESPACE " "
IDENT_PAT
NAME
IDENT "foo"
WHITESPACE " "
EQ "="
WHITESPACE " "
MACRO_EXPR
MACRO_CALL
PATH
PATH_SEGMENT
NAME_REF
IDENT "macro_rules"
BANG "!"
TOKEN_TREE
L_PAREN "("
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"

View file

@ -0,0 +1,6 @@
macro_rules! {}
macro_rules! ();
macro_rules! [];
fn main() {
let foo = macro_rules!();
}