mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-02 21:04:18 +00:00
Better parser recovery for macro calls in type bound position
This commit is contained in:
parent
634596e2d7
commit
5d3001795a
6 changed files with 134 additions and 10 deletions
|
|
@ -201,6 +201,17 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
|
|||
}
|
||||
if paths::is_use_path_start(p) {
|
||||
types::path_type_bounds(p, false);
|
||||
// test_err type_bounds_macro_call_recovery
|
||||
// fn foo<T: T![], T: T!, T: T!{}>() -> Box<T! + T!{}> {}
|
||||
if p.at(T![!]) {
|
||||
let m = p.start();
|
||||
p.bump(T![!]);
|
||||
p.error("unexpected `!` in type path, macro calls are not allowed here");
|
||||
if p.at_ts(TokenSet::new(&[T!['{'], T!['['], T!['(']])) {
|
||||
items::token_tree(p);
|
||||
}
|
||||
m.complete(p, ERROR);
|
||||
}
|
||||
} else {
|
||||
m.abandon(p);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option<Completed
|
|||
types::type_(p);
|
||||
if p.eat(T![as]) {
|
||||
if is_use_path_start(p) {
|
||||
types::path_type(p);
|
||||
types::path_type_bounds(p, true);
|
||||
} else {
|
||||
p.error("expected a trait");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,15 +330,6 @@ fn bare_dyn_trait_type(p: &mut Parser<'_>) {
|
|||
m.complete(p, DYN_TRAIT_TYPE);
|
||||
}
|
||||
|
||||
// test path_type
|
||||
// type A = Foo;
|
||||
// type B = ::Foo;
|
||||
// type C = self::Foo;
|
||||
// type D = super::Foo;
|
||||
pub(super) fn path_type(p: &mut Parser<'_>) {
|
||||
path_type_bounds(p, true);
|
||||
}
|
||||
|
||||
// test macro_call_type
|
||||
// type A = foo!();
|
||||
// type B = crate::foo!();
|
||||
|
|
@ -365,6 +356,11 @@ fn path_or_macro_type(p: &mut Parser<'_>, allow_bounds: bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// test path_type
|
||||
// type A = Foo;
|
||||
// type B = ::Foo;
|
||||
// type C = self::Foo;
|
||||
// type D = super::Foo;
|
||||
pub(super) fn path_type_bounds(p: &mut Parser<'_>, allow_bounds: bool) {
|
||||
assert!(paths::is_path_start(p));
|
||||
let m = p.start();
|
||||
|
|
|
|||
|
|
@ -876,6 +876,10 @@ mod err {
|
|||
run_and_expect_errors("test_data/parser/inline/err/tuple_pat_leading_comma.rs");
|
||||
}
|
||||
#[test]
|
||||
fn type_bounds_macro_call_recovery() {
|
||||
run_and_expect_errors("test_data/parser/inline/err/type_bounds_macro_call_recovery.rs");
|
||||
}
|
||||
#[test]
|
||||
fn type_in_array_recover() {
|
||||
run_and_expect_errors("test_data/parser/inline/err/type_in_array_recover.rs");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
SOURCE_FILE
|
||||
FN
|
||||
FN_KW "fn"
|
||||
WHITESPACE " "
|
||||
NAME
|
||||
IDENT "foo"
|
||||
GENERIC_PARAM_LIST
|
||||
L_ANGLE "<"
|
||||
TYPE_PARAM
|
||||
NAME
|
||||
IDENT "T"
|
||||
COLON ":"
|
||||
WHITESPACE " "
|
||||
TYPE_BOUND_LIST
|
||||
TYPE_BOUND
|
||||
PATH_TYPE
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "T"
|
||||
ERROR
|
||||
BANG "!"
|
||||
TOKEN_TREE
|
||||
L_BRACK "["
|
||||
R_BRACK "]"
|
||||
COMMA ","
|
||||
WHITESPACE " "
|
||||
TYPE_PARAM
|
||||
NAME
|
||||
IDENT "T"
|
||||
COLON ":"
|
||||
WHITESPACE " "
|
||||
TYPE_BOUND_LIST
|
||||
TYPE_BOUND
|
||||
PATH_TYPE
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "T"
|
||||
ERROR
|
||||
BANG "!"
|
||||
COMMA ","
|
||||
WHITESPACE " "
|
||||
TYPE_PARAM
|
||||
NAME
|
||||
IDENT "T"
|
||||
COLON ":"
|
||||
WHITESPACE " "
|
||||
TYPE_BOUND_LIST
|
||||
TYPE_BOUND
|
||||
PATH_TYPE
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "T"
|
||||
ERROR
|
||||
BANG "!"
|
||||
TOKEN_TREE
|
||||
L_CURLY "{"
|
||||
R_CURLY "}"
|
||||
R_ANGLE ">"
|
||||
PARAM_LIST
|
||||
L_PAREN "("
|
||||
R_PAREN ")"
|
||||
WHITESPACE " "
|
||||
RET_TYPE
|
||||
THIN_ARROW "->"
|
||||
WHITESPACE " "
|
||||
PATH_TYPE
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "Box"
|
||||
GENERIC_ARG_LIST
|
||||
L_ANGLE "<"
|
||||
TYPE_ARG
|
||||
DYN_TRAIT_TYPE
|
||||
TYPE_BOUND_LIST
|
||||
TYPE_BOUND
|
||||
MACRO_TYPE
|
||||
MACRO_CALL
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "T"
|
||||
BANG "!"
|
||||
WHITESPACE " "
|
||||
PLUS "+"
|
||||
WHITESPACE " "
|
||||
TYPE_BOUND
|
||||
PATH_TYPE
|
||||
PATH
|
||||
PATH_SEGMENT
|
||||
NAME_REF
|
||||
IDENT "T"
|
||||
ERROR
|
||||
BANG "!"
|
||||
TOKEN_TREE
|
||||
L_CURLY "{"
|
||||
R_CURLY "}"
|
||||
R_ANGLE ">"
|
||||
WHITESPACE " "
|
||||
BLOCK_EXPR
|
||||
STMT_LIST
|
||||
L_CURLY "{"
|
||||
R_CURLY "}"
|
||||
WHITESPACE "\n"
|
||||
error 12: unexpected `!` in type path, macro calls are not allowed here
|
||||
error 21: unexpected `!` in type path, macro calls are not allowed here
|
||||
error 28: unexpected `!` in type path, macro calls are not allowed here
|
||||
error 43: expected `{`, `[`, `(`
|
||||
error 48: unexpected `!` in type path, macro calls are not allowed here
|
||||
|
|
@ -0,0 +1 @@
|
|||
fn foo<T: T![], T: T!, T: T!{}>() -> Box<T! + T!{}> {}
|
||||
Loading…
Add table
Add a link
Reference in a new issue