Parse bare dyn types with leading lifetime
This commit is contained in:
parent
0dd94d3b07
commit
2a509d0eb2
@ -35,7 +35,7 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser<'_>, colon_colon_required: boo
|
|||||||
// type T = S<i32>;
|
// type T = S<i32>;
|
||||||
fn generic_arg(p: &mut Parser<'_>) -> bool {
|
fn generic_arg(p: &mut Parser<'_>) -> bool {
|
||||||
match p.current() {
|
match p.current() {
|
||||||
LIFETIME_IDENT => lifetime_arg(p),
|
LIFETIME_IDENT if !p.nth_at(1, T![+]) => lifetime_arg(p),
|
||||||
T!['{'] | T![true] | T![false] | T![-] => const_arg(p),
|
T!['{'] | T![true] | T![false] | T![-] => const_arg(p),
|
||||||
k if k.is_literal() => const_arg(p),
|
k if k.is_literal() => const_arg(p),
|
||||||
// test associated_type_bounds
|
// test associated_type_bounds
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
T![impl],
|
T![impl],
|
||||||
T![dyn],
|
T![dyn],
|
||||||
T![Self],
|
T![Self],
|
||||||
|
LIFETIME_IDENT,
|
||||||
]));
|
]));
|
||||||
|
|
||||||
pub(super) const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[
|
pub(super) const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[
|
||||||
@ -49,6 +50,7 @@ fn type_with_bounds_cond(p: &mut Parser<'_>, allow_bounds: bool) {
|
|||||||
// Some path types are not allowed to have bounds (no plus)
|
// Some path types are not allowed to have bounds (no plus)
|
||||||
T![<] => path_type_(p, allow_bounds),
|
T![<] => path_type_(p, allow_bounds),
|
||||||
_ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
|
_ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
|
||||||
|
LIFETIME_IDENT if p.nth_at(1, T![+]) => bare_dyn_trait_type(p),
|
||||||
_ => {
|
_ => {
|
||||||
p.err_recover("expected type", TYPE_RECOVERY_SET);
|
p.err_recover("expected type", TYPE_RECOVERY_SET);
|
||||||
}
|
}
|
||||||
@ -275,6 +277,15 @@ fn dyn_trait_type(p: &mut Parser<'_>) {
|
|||||||
m.complete(p, DYN_TRAIT_TYPE);
|
m.complete(p, DYN_TRAIT_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test bare_dyn_types_with_leading_lifetime
|
||||||
|
// type A = 'static + Trait;
|
||||||
|
// type B = S<'static + Trait>;
|
||||||
|
fn bare_dyn_trait_type(p: &mut Parser<'_>) {
|
||||||
|
let m = p.start();
|
||||||
|
generic_params::bounds_without_colon(p);
|
||||||
|
m.complete(p, DYN_TRAIT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
// test path_type
|
// test path_type
|
||||||
// type A = Foo;
|
// type A = Foo;
|
||||||
// type B = ::Foo;
|
// type B = ::Foo;
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
SOURCE_FILE
|
||||||
|
TYPE_ALIAS
|
||||||
|
TYPE_KW "type"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "A"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
DYN_TRAIT_TYPE
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
LIFETIME
|
||||||
|
LIFETIME_IDENT "'static"
|
||||||
|
WHITESPACE " "
|
||||||
|
PLUS "+"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Trait"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
||||||
|
TYPE_ALIAS
|
||||||
|
TYPE_KW "type"
|
||||||
|
WHITESPACE " "
|
||||||
|
NAME
|
||||||
|
IDENT "B"
|
||||||
|
WHITESPACE " "
|
||||||
|
EQ "="
|
||||||
|
WHITESPACE " "
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "S"
|
||||||
|
GENERIC_ARG_LIST
|
||||||
|
L_ANGLE "<"
|
||||||
|
TYPE_ARG
|
||||||
|
DYN_TRAIT_TYPE
|
||||||
|
TYPE_BOUND_LIST
|
||||||
|
TYPE_BOUND
|
||||||
|
LIFETIME
|
||||||
|
LIFETIME_IDENT "'static"
|
||||||
|
WHITESPACE " "
|
||||||
|
PLUS "+"
|
||||||
|
WHITESPACE " "
|
||||||
|
TYPE_BOUND
|
||||||
|
PATH_TYPE
|
||||||
|
PATH
|
||||||
|
PATH_SEGMENT
|
||||||
|
NAME_REF
|
||||||
|
IDENT "Trait"
|
||||||
|
R_ANGLE ">"
|
||||||
|
SEMICOLON ";"
|
||||||
|
WHITESPACE "\n"
|
@ -0,0 +1,2 @@
|
|||||||
|
type A = 'static + Trait;
|
||||||
|
type B = S<'static + Trait>;
|
Loading…
Reference in New Issue
Block a user