Auto merge of #14739 - lowr:fix/type-with-leading-lifetime, r=Veykril
Parse bare dyn types with leading lifetime TIL types may start with a lifetime identifier e.g. `type A = 'static + Trait;`. When parsing types, leading lifetime followed by a plus sign should be parsed as a bare dyn type rather than a generic lifetime argument or error type (which is what we produce today). Although it's no longer accepted since Rust 2021, it wouldn't hurt to support this obsolete syntax.
This commit is contained in:
commit
e461e53f01
@ -35,7 +35,7 @@ const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[
|
||||
// type T = S<i32>;
|
||||
fn generic_arg(p: &mut Parser<'_>) -> bool {
|
||||
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),
|
||||
k if k.is_literal() => const_arg(p),
|
||||
// test associated_type_bounds
|
||||
|
@ -15,6 +15,7 @@ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[
|
||||
T![impl],
|
||||
T![dyn],
|
||||
T![Self],
|
||||
LIFETIME_IDENT,
|
||||
]));
|
||||
|
||||
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)
|
||||
T![<] => path_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);
|
||||
}
|
||||
@ -275,6 +277,15 @@ fn dyn_trait_type(p: &mut Parser<'_>) {
|
||||
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
|
||||
// type A = 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…
x
Reference in New Issue
Block a user