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:
bors 2023-05-05 09:23:32 +00:00
commit e461e53f01
4 changed files with 72 additions and 1 deletions

View File

@ -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

View File

@ -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;

View File

@ -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"

View File

@ -0,0 +1,2 @@
type A = 'static + Trait;
type B = S<'static + Trait>;