Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/parser/src/grammar/generic_args.rs5
-rw-r--r--crates/parser/src/grammar/types.rs2
-rw-r--r--crates/parser/test_data/generated/runner.rs7
-rw-r--r--crates/parser/test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rast32
-rw-r--r--crates/parser/test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rs2
-rw-r--r--crates/parser/test_data/parser/inline/ok/generic_arg.rast21
-rw-r--r--crates/parser/test_data/parser/inline/ok/generic_arg.rs2
7 files changed, 68 insertions, 3 deletions
diff --git a/crates/parser/src/grammar/generic_args.rs b/crates/parser/src/grammar/generic_args.rs
index c7d8040b24..b9d5bff663 100644
--- a/crates/parser/src/grammar/generic_args.rs
+++ b/crates/parser/src/grammar/generic_args.rs
@@ -45,7 +45,7 @@ pub(crate) const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[
const GENERIC_ARG_RECOVERY_SET: TokenSet = TokenSet::new(&[T![>], T![,]]);
// test generic_arg
-// type T = S<i32>;
+// type T = S<i32, dyn T, fn()>;
pub(crate) fn generic_arg(p: &mut Parser<'_>) -> bool {
match p.current() {
LIFETIME_IDENT if !p.nth_at(1, T![+]) => lifetime_arg(p),
@@ -57,6 +57,9 @@ pub(crate) fn generic_arg(p: &mut Parser<'_>) -> bool {
// type ParenthesizedArgs = Foo<Item(T), Item::(T), Item(T): Bound, Item::(T): Bound, Item(T) = Item, Item::(T) = Item>;
// type RTN = Foo<Item(..), Item(..), Item(..): Bound, Item(..): Bound, Item(..) = Item, Item(..) = Item>;
+ // test edition_2015_dyn_prefix_inside_generic_arg 2015
+ // type A = Foo<dyn T>;
+ T![ident] if !p.edition().at_least_2018() && types::is_dyn_weak(p) => type_arg(p),
// test macro_inside_generic_arg
// type A = Foo<syn::Token![_]>;
k if PATH_NAME_REF_KINDS.contains(k) => {
diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs
index 35198ccbe3..0133b7d5d8 100644
--- a/crates/parser/src/grammar/types.rs
+++ b/crates/parser/src/grammar/types.rs
@@ -58,7 +58,7 @@ fn type_with_bounds_cond(p: &mut Parser<'_>, allow_bounds: bool) {
}
}
-fn is_dyn_weak(p: &Parser<'_>) -> bool {
+pub(crate) fn is_dyn_weak(p: &Parser<'_>) -> bool {
const WEAK_DYN_PATH_FIRST: TokenSet = TokenSet::new(&[
IDENT,
T![self],
diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs
index f9486f53c2..0beaf1ae3a 100644
--- a/crates/parser/test_data/generated/runner.rs
+++ b/crates/parser/test_data/generated/runner.rs
@@ -190,6 +190,13 @@ mod ok {
);
}
#[test]
+ fn edition_2015_dyn_prefix_inside_generic_arg() {
+ run_and_expect_no_errors_with_edition(
+ "test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rs",
+ crate::Edition::Edition2015,
+ );
+ }
+ #[test]
fn effect_blocks() { run_and_expect_no_errors("test_data/parser/inline/ok/effect_blocks.rs"); }
#[test]
fn exclusive_range_pat() {
diff --git a/crates/parser/test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rast b/crates/parser/test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rast
new file mode 100644
index 0000000000..24e671b343
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rast
@@ -0,0 +1,32 @@
+SOURCE_FILE
+ TYPE_ALIAS
+ COMMENT "// 2015"
+ WHITESPACE "\n"
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "A"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Foo"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ DYN_TRAIT_TYPE
+ DYN_KW "dyn"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rs b/crates/parser/test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rs
new file mode 100644
index 0000000000..84cece5748
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/edition_2015_dyn_prefix_inside_generic_arg.rs
@@ -0,0 +1,2 @@
+// 2015
+type A = Foo<dyn T>;
diff --git a/crates/parser/test_data/parser/inline/ok/generic_arg.rast b/crates/parser/test_data/parser/inline/ok/generic_arg.rast
index 5a01f154ba..e32cf08565 100644
--- a/crates/parser/test_data/parser/inline/ok/generic_arg.rast
+++ b/crates/parser/test_data/parser/inline/ok/generic_arg.rast
@@ -20,6 +20,27 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "i32"
+ COMMA ","
+ WHITESPACE " "
+ TYPE_ARG
+ DYN_TRAIT_TYPE
+ DYN_KW "dyn"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ COMMA ","
+ WHITESPACE " "
+ TYPE_ARG
+ FN_PTR_TYPE
+ FN_KW "fn"
+ PARAM_LIST
+ L_PAREN "("
+ R_PAREN ")"
R_ANGLE ">"
SEMICOLON ";"
WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/generic_arg.rs b/crates/parser/test_data/parser/inline/ok/generic_arg.rs
index f2ccc558bb..cf991b5b36 100644
--- a/crates/parser/test_data/parser/inline/ok/generic_arg.rs
+++ b/crates/parser/test_data/parser/inline/ok/generic_arg.rs
@@ -1 +1 @@
-type T = S<i32>;
+type T = S<i32, dyn T, fn()>;