mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-01 20:31:59 +00:00
Merge commit 'a911652360' into sync-from-ra
This commit is contained in:
parent
0661390ad4
commit
e4866b6ddb
315 changed files with 7088 additions and 4415 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
macro_rules! {};
|
||||
macro_rules! ()
|
||||
macro_rules! []
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
use {a;
|
||||
use b;
|
||||
struct T;
|
||||
fn test() {}
|
||||
|
|
@ -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"
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
macro_rules! {}
|
||||
macro_rules! ();
|
||||
macro_rules! [];
|
||||
fn main() {
|
||||
let foo = macro_rules!();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue