Unnamed repository; edit this file 'description' to name the repository.
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.
bors 2023-05-05
parent 0dd94d3 · parent 2a509d0 · commit e461e53
-rw-r--r--crates/parser/src/grammar/generic_args.rs2
-rw-r--r--crates/parser/src/grammar/types.rs11
-rw-r--r--crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rast58
-rw-r--r--crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rs2
4 files changed, 72 insertions, 1 deletions
diff --git a/crates/parser/src/grammar/generic_args.rs b/crates/parser/src/grammar/generic_args.rs
index 55794954a8..4cac04a32a 100644
--- a/crates/parser/src/grammar/generic_args.rs
+++ b/crates/parser/src/grammar/generic_args.rs
@@ -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
diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs
index 5ae16475b6..26dac87956 100644
--- a/crates/parser/src/grammar/types.rs
+++ b/crates/parser/src/grammar/types.rs
@@ -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;
diff --git a/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rast b/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rast
new file mode 100644
index 0000000000..d7e67fbcd1
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rast
@@ -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"
diff --git a/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rs b/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rs
new file mode 100644
index 0000000000..3e9a9a29dd
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/0208_bare_dyn_types_with_leading_lifetime.rs
@@ -0,0 +1,2 @@
+type A = 'static + Trait;
+type B = S<'static + Trait>;