diff options
5 files changed, 85 insertions, 9 deletions
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index c7aaccc95..47107a58b 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -1716,6 +1716,7 @@ impl ToOwned for LifetimeParam { | |||
1716 | } | 1716 | } |
1717 | 1717 | ||
1718 | 1718 | ||
1719 | impl ast::AttrsOwner for LifetimeParam {} | ||
1719 | impl LifetimeParam { | 1720 | impl LifetimeParam { |
1720 | pub fn lifetime(&self) -> Option<&Lifetime> { | 1721 | pub fn lifetime(&self) -> Option<&Lifetime> { |
1721 | super::child_opt(self) | 1722 | super::child_opt(self) |
@@ -4076,6 +4077,7 @@ impl ToOwned for TypeParam { | |||
4076 | 4077 | ||
4077 | 4078 | ||
4078 | impl ast::NameOwner for TypeParam {} | 4079 | impl ast::NameOwner for TypeParam {} |
4080 | impl ast::AttrsOwner for TypeParam {} | ||
4079 | impl TypeParam {} | 4081 | impl TypeParam {} |
4080 | 4082 | ||
4081 | // TypeParamList | 4083 | // TypeParamList |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 193b563aa..b1775d0f8 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -559,8 +559,11 @@ Grammar( | |||
559 | ["lifetime_params", "LifetimeParam" ], | 559 | ["lifetime_params", "LifetimeParam" ], |
560 | ] | 560 | ] |
561 | ), | 561 | ), |
562 | "TypeParam": ( traits: ["NameOwner"] ), | 562 | "TypeParam": ( traits: ["NameOwner", "AttrsOwner"] ), |
563 | "LifetimeParam": ( options: [ "Lifetime" ] ), | 563 | "LifetimeParam": ( |
564 | options: [ "Lifetime"], | ||
565 | traits: ["AttrsOwner"], | ||
566 | ), | ||
564 | "Lifetime": ( traits: ["AstToken"] ), | 567 | "Lifetime": ( traits: ["AstToken"] ), |
565 | "WhereClause": (), | 568 | "WhereClause": (), |
566 | "ExprStmt": ( | 569 | "ExprStmt": ( |
diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs index 1ec813b3e..40f998682 100644 --- a/crates/ra_syntax/src/grammar/type_params.rs +++ b/crates/ra_syntax/src/grammar/type_params.rs | |||
@@ -13,10 +13,20 @@ fn type_param_list(p: &mut Parser) { | |||
13 | p.bump(); | 13 | p.bump(); |
14 | 14 | ||
15 | while !p.at(EOF) && !p.at(R_ANGLE) { | 15 | while !p.at(EOF) && !p.at(R_ANGLE) { |
16 | let m = p.start(); | ||
17 | |||
18 | // test generic_lifetime_type_attribute | ||
19 | // fn foo<#[derive(Lifetime)] 'a, #[derive(Type)] T>(_: &'a T) { | ||
20 | // } | ||
21 | attributes::outer_attributes(p); | ||
22 | |||
16 | match p.current() { | 23 | match p.current() { |
17 | LIFETIME => lifetime_param(p), | 24 | LIFETIME => lifetime_param(p, m), |
18 | IDENT => type_param(p), | 25 | IDENT => type_param(p, m), |
19 | _ => p.err_and_bump("expected type parameter"), | 26 | _ => { |
27 | m.abandon(p); | ||
28 | p.err_and_bump("expected type parameter") | ||
29 | } | ||
20 | } | 30 | } |
21 | if !p.at(R_ANGLE) && !p.expect(COMMA) { | 31 | if !p.at(R_ANGLE) && !p.expect(COMMA) { |
22 | break; | 32 | break; |
@@ -26,9 +36,8 @@ fn type_param_list(p: &mut Parser) { | |||
26 | m.complete(p, TYPE_PARAM_LIST); | 36 | m.complete(p, TYPE_PARAM_LIST); |
27 | } | 37 | } |
28 | 38 | ||
29 | fn lifetime_param(p: &mut Parser) { | 39 | fn lifetime_param(p: &mut Parser, m: Marker) { |
30 | assert!(p.at(LIFETIME)); | 40 | assert!(p.at(LIFETIME)); |
31 | let m = p.start(); | ||
32 | p.bump(); | 41 | p.bump(); |
33 | if p.at(COLON) { | 42 | if p.at(COLON) { |
34 | lifetime_bounds(p); | 43 | lifetime_bounds(p); |
@@ -36,9 +45,8 @@ fn lifetime_param(p: &mut Parser) { | |||
36 | m.complete(p, LIFETIME_PARAM); | 45 | m.complete(p, LIFETIME_PARAM); |
37 | } | 46 | } |
38 | 47 | ||
39 | fn type_param(p: &mut Parser) { | 48 | fn type_param(p: &mut Parser, m: Marker) { |
40 | assert!(p.at(IDENT)); | 49 | assert!(p.at(IDENT)); |
41 | let m = p.start(); | ||
42 | name(p); | 50 | name(p); |
43 | if p.at(COLON) { | 51 | if p.at(COLON) { |
44 | bounds(p); | 52 | bounds(p); |
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0122_generic_lifetime_type_attribute.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0122_generic_lifetime_type_attribute.rs new file mode 100644 index 000000000..e8fdf741f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0122_generic_lifetime_type_attribute.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | fn foo<#[derive(Lifetime)] 'a, #[derive(Type)] T>(_: &'a T) { | ||
2 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt new file mode 100644 index 000000000..6a6aa89e8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0122_generic_lifetime_type_attribute.txt | |||
@@ -0,0 +1,61 @@ | |||
1 | SOURCE_FILE@[0; 64) | ||
2 | FN_DEF@[0; 63) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | TYPE_PARAM_LIST@[6; 49) | ||
8 | L_ANGLE@[6; 7) | ||
9 | LIFETIME_PARAM@[7; 29) | ||
10 | ATTR@[7; 26) | ||
11 | POUND@[7; 8) | ||
12 | TOKEN_TREE@[8; 26) | ||
13 | L_BRACK@[8; 9) | ||
14 | IDENT@[9; 15) "derive" | ||
15 | TOKEN_TREE@[15; 25) | ||
16 | L_PAREN@[15; 16) | ||
17 | IDENT@[16; 24) "Lifetime" | ||
18 | R_PAREN@[24; 25) | ||
19 | R_BRACK@[25; 26) | ||
20 | WHITESPACE@[26; 27) | ||
21 | LIFETIME@[27; 29) "'a" | ||
22 | COMMA@[29; 30) | ||
23 | WHITESPACE@[30; 31) | ||
24 | TYPE_PARAM@[31; 48) | ||
25 | ATTR@[31; 46) | ||
26 | POUND@[31; 32) | ||
27 | TOKEN_TREE@[32; 46) | ||
28 | L_BRACK@[32; 33) | ||
29 | IDENT@[33; 39) "derive" | ||
30 | TOKEN_TREE@[39; 45) | ||
31 | L_PAREN@[39; 40) | ||
32 | IDENT@[40; 44) "Type" | ||
33 | R_PAREN@[44; 45) | ||
34 | R_BRACK@[45; 46) | ||
35 | WHITESPACE@[46; 47) | ||
36 | NAME@[47; 48) | ||
37 | IDENT@[47; 48) "T" | ||
38 | R_ANGLE@[48; 49) | ||
39 | PARAM_LIST@[49; 59) | ||
40 | L_PAREN@[49; 50) | ||
41 | PARAM@[50; 58) | ||
42 | PLACEHOLDER_PAT@[50; 51) | ||
43 | UNDERSCORE@[50; 51) | ||
44 | COLON@[51; 52) | ||
45 | WHITESPACE@[52; 53) | ||
46 | REFERENCE_TYPE@[53; 58) | ||
47 | AMP@[53; 54) | ||
48 | LIFETIME@[54; 56) "'a" | ||
49 | WHITESPACE@[56; 57) | ||
50 | PATH_TYPE@[57; 58) | ||
51 | PATH@[57; 58) | ||
52 | PATH_SEGMENT@[57; 58) | ||
53 | NAME_REF@[57; 58) | ||
54 | IDENT@[57; 58) "T" | ||
55 | R_PAREN@[58; 59) | ||
56 | WHITESPACE@[59; 60) | ||
57 | BLOCK@[60; 63) | ||
58 | L_CURLY@[60; 61) | ||
59 | WHITESPACE@[61; 62) | ||
60 | R_CURLY@[62; 63) | ||
61 | WHITESPACE@[63; 64) | ||