diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-01-06 23:43:24 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-01-06 23:43:24 +0000 |
commit | 7b9df1062d65e6977f16d6595ffb5912769011a3 (patch) | |
tree | 8a9535261dac04f171caa68d4b908cdde0b4a34c /crates | |
parent | c92a090f49cad2fa540562536f07fcb619f16680 (diff) | |
parent | ce1b34fd59a6145a4bb5682d672c846e101725d4 (diff) |
Merge #2724
2724: Improve const generic parsing r=matklad a=mchesser
Add support for generic arguments in:
`impl` type parameters:
```rust
impl<const N: u32> Bar<N> {}
```
type args:
```rust
type A = B<1, { 2 }>;
test::<10>();
```
Co-authored-by: Michael Chesser <[email protected]>
Diffstat (limited to 'crates')
8 files changed, 120 insertions, 21 deletions
diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs index 2c560e824..964fd3041 100644 --- a/crates/ra_parser/src/grammar/items/traits.rs +++ b/crates/ra_parser/src/grammar/items/traits.rs | |||
@@ -100,6 +100,8 @@ pub(crate) fn impl_item_list(p: &mut Parser) { | |||
100 | m.complete(p, ITEM_LIST); | 100 | m.complete(p, ITEM_LIST); |
101 | } | 101 | } |
102 | 102 | ||
103 | // test impl_type_params | ||
104 | // impl<const N: u32> Bar<N> {} | ||
103 | fn choose_type_params_over_qpath(p: &Parser) -> bool { | 105 | fn choose_type_params_over_qpath(p: &Parser) -> bool { |
104 | // There's an ambiguity between generic parameters and qualified paths in impls. | 106 | // There's an ambiguity between generic parameters and qualified paths in impls. |
105 | // If we see `<` it may start both, so we have to inspect some following tokens. | 107 | // If we see `<` it may start both, so we have to inspect some following tokens. |
@@ -107,6 +109,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool { | |||
107 | // but not qualified paths (with one exception): | 109 | // but not qualified paths (with one exception): |
108 | // `<` `>` - empty generic parameters | 110 | // `<` `>` - empty generic parameters |
109 | // `<` `#` - generic parameters with attributes | 111 | // `<` `#` - generic parameters with attributes |
112 | // `<` `const` - const generic parameters | ||
110 | // `<` (LIFETIME|IDENT) `>` - single generic parameter | 113 | // `<` (LIFETIME|IDENT) `>` - single generic parameter |
111 | // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list | 114 | // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list |
112 | // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds | 115 | // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds |
@@ -119,7 +122,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool { | |||
119 | if !p.at(T![<]) { | 122 | if !p.at(T![<]) { |
120 | return false; | 123 | return false; |
121 | } | 124 | } |
122 | if p.nth(1) == T![#] || p.nth(1) == T![>] { | 125 | if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW { |
123 | return true; | 126 | return true; |
124 | } | 127 | } |
125 | (p.nth(1) == LIFETIME || p.nth(1) == IDENT) | 128 | (p.nth(1) == LIFETIME || p.nth(1) == IDENT) |
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs index 7256c2697..33d9973e9 100644 --- a/crates/ra_parser/src/grammar/type_args.rs +++ b/crates/ra_parser/src/grammar/type_args.rs | |||
@@ -26,7 +26,7 @@ pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) { | |||
26 | } | 26 | } |
27 | 27 | ||
28 | // test type_arg | 28 | // test type_arg |
29 | // type A = B<'static, i32, Item=u64>; | 29 | // type A = B<'static, i32, 1, { 2 }, Item=u64>; |
30 | fn type_arg(p: &mut Parser) { | 30 | fn type_arg(p: &mut Parser) { |
31 | let m = p.start(); | 31 | let m = p.start(); |
32 | match p.current() { | 32 | match p.current() { |
@@ -47,6 +47,14 @@ fn type_arg(p: &mut Parser) { | |||
47 | types::type_(p); | 47 | types::type_(p); |
48 | m.complete(p, ASSOC_TYPE_ARG); | 48 | m.complete(p, ASSOC_TYPE_ARG); |
49 | } | 49 | } |
50 | T!['{'] => { | ||
51 | expressions::block(p); | ||
52 | m.complete(p, CONST_ARG); | ||
53 | } | ||
54 | k if k.is_literal() => { | ||
55 | p.bump(k); | ||
56 | m.complete(p, CONST_ARG); | ||
57 | } | ||
50 | _ => { | 58 | _ => { |
51 | types::type_(p); | 59 | types::type_(p); |
52 | m.complete(p, TYPE_ARG); | 60 | m.complete(p, TYPE_ARG); |
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index 262c545e4..4b301d67a 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs | |||
@@ -234,6 +234,7 @@ pub enum SyntaxKind { | |||
234 | LIFETIME_ARG, | 234 | LIFETIME_ARG, |
235 | TYPE_ARG, | 235 | TYPE_ARG, |
236 | ASSOC_TYPE_ARG, | 236 | ASSOC_TYPE_ARG, |
237 | CONST_ARG, | ||
237 | PARAM_LIST, | 238 | PARAM_LIST, |
238 | PARAM, | 239 | PARAM, |
239 | SELF_PARAM, | 240 | SELF_PARAM, |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 2eb4b14d2..33d5578e7 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -3114,6 +3114,9 @@ impl TypeArgList { | |||
3114 | pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> { | 3114 | pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> { |
3115 | AstChildren::new(&self.syntax) | 3115 | AstChildren::new(&self.syntax) |
3116 | } | 3116 | } |
3117 | pub fn const_arg(&self) -> AstChildren<ConstArg> { | ||
3118 | AstChildren::new(&self.syntax) | ||
3119 | } | ||
3117 | } | 3120 | } |
3118 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 3121 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
3119 | pub struct TypeArg { | 3122 | pub struct TypeArg { |
@@ -3196,6 +3199,36 @@ impl AstNode for LifetimeArg { | |||
3196 | } | 3199 | } |
3197 | impl LifetimeArg {} | 3200 | impl LifetimeArg {} |
3198 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 3201 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
3202 | pub struct ConstArg { | ||
3203 | pub(crate) syntax: SyntaxNode, | ||
3204 | } | ||
3205 | impl AstNode for ConstArg { | ||
3206 | fn can_cast(kind: SyntaxKind) -> bool { | ||
3207 | match kind { | ||
3208 | CONST_ARG => true, | ||
3209 | _ => false, | ||
3210 | } | ||
3211 | } | ||
3212 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
3213 | if Self::can_cast(syntax.kind()) { | ||
3214 | Some(Self { syntax }) | ||
3215 | } else { | ||
3216 | None | ||
3217 | } | ||
3218 | } | ||
3219 | fn syntax(&self) -> &SyntaxNode { | ||
3220 | &self.syntax | ||
3221 | } | ||
3222 | } | ||
3223 | impl ConstArg { | ||
3224 | pub fn literal(&self) -> Option<Literal> { | ||
3225 | AstChildren::new(&self.syntax).next() | ||
3226 | } | ||
3227 | pub fn block_expr(&self) -> Option<BlockExpr> { | ||
3228 | AstChildren::new(&self.syntax).next() | ||
3229 | } | ||
3230 | } | ||
3231 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
3199 | pub struct MacroItems { | 3232 | pub struct MacroItems { |
3200 | pub(crate) syntax: SyntaxNode, | 3233 | pub(crate) syntax: SyntaxNode, |
3201 | } | 3234 | } |
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rs b/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rs index 385c43131..0d07d7651 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rs +++ b/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rs | |||
@@ -1 +1 @@ | |||
type A = B<'static, i32, Item=u64>; | type A = B<'static, i32, 1, { 2 }, Item=u64>; | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt b/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt index 4786bf77a..025faf5ca 100644 --- a/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt +++ b/crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt | |||
@@ -1,5 +1,5 @@ | |||
1 | SOURCE_FILE@[0; 36) | 1 | SOURCE_FILE@[0; 46) |
2 | TYPE_ALIAS_DEF@[0; 35) | 2 | TYPE_ALIAS_DEF@[0; 45) |
3 | TYPE_KW@[0; 4) "type" | 3 | TYPE_KW@[0; 4) "type" |
4 | WHITESPACE@[4; 5) " " | 4 | WHITESPACE@[4; 5) " " |
5 | NAME@[5; 6) | 5 | NAME@[5; 6) |
@@ -7,12 +7,12 @@ SOURCE_FILE@[0; 36) | |||
7 | WHITESPACE@[6; 7) " " | 7 | WHITESPACE@[6; 7) " " |
8 | EQ@[7; 8) "=" | 8 | EQ@[7; 8) "=" |
9 | WHITESPACE@[8; 9) " " | 9 | WHITESPACE@[8; 9) " " |
10 | PATH_TYPE@[9; 34) | 10 | PATH_TYPE@[9; 44) |
11 | PATH@[9; 34) | 11 | PATH@[9; 44) |
12 | PATH_SEGMENT@[9; 34) | 12 | PATH_SEGMENT@[9; 44) |
13 | NAME_REF@[9; 10) | 13 | NAME_REF@[9; 10) |
14 | IDENT@[9; 10) "B" | 14 | IDENT@[9; 10) "B" |
15 | TYPE_ARG_LIST@[10; 34) | 15 | TYPE_ARG_LIST@[10; 44) |
16 | L_ANGLE@[10; 11) "<" | 16 | L_ANGLE@[10; 11) "<" |
17 | LIFETIME_ARG@[11; 18) | 17 | LIFETIME_ARG@[11; 18) |
18 | LIFETIME@[11; 18) "\'static" | 18 | LIFETIME@[11; 18) "\'static" |
@@ -26,15 +26,30 @@ SOURCE_FILE@[0; 36) | |||
26 | IDENT@[20; 23) "i32" | 26 | IDENT@[20; 23) "i32" |
27 | COMMA@[23; 24) "," | 27 | COMMA@[23; 24) "," |
28 | WHITESPACE@[24; 25) " " | 28 | WHITESPACE@[24; 25) " " |
29 | ASSOC_TYPE_ARG@[25; 33) | 29 | CONST_ARG@[25; 26) |
30 | NAME_REF@[25; 29) | 30 | INT_NUMBER@[25; 26) "1" |
31 | IDENT@[25; 29) "Item" | 31 | COMMA@[26; 27) "," |
32 | EQ@[29; 30) "=" | 32 | WHITESPACE@[27; 28) " " |
33 | PATH_TYPE@[30; 33) | 33 | CONST_ARG@[28; 33) |
34 | PATH@[30; 33) | 34 | BLOCK_EXPR@[28; 33) |
35 | PATH_SEGMENT@[30; 33) | 35 | BLOCK@[28; 33) |
36 | NAME_REF@[30; 33) | 36 | L_CURLY@[28; 29) "{" |
37 | IDENT@[30; 33) "u64" | 37 | WHITESPACE@[29; 30) " " |
38 | R_ANGLE@[33; 34) ">" | 38 | LITERAL@[30; 31) |
39 | SEMI@[34; 35) ";" | 39 | INT_NUMBER@[30; 31) "2" |
40 | WHITESPACE@[35; 36) "\n" | 40 | WHITESPACE@[31; 32) " " |
41 | R_CURLY@[32; 33) "}" | ||
42 | COMMA@[33; 34) "," | ||
43 | WHITESPACE@[34; 35) " " | ||
44 | ASSOC_TYPE_ARG@[35; 43) | ||
45 | NAME_REF@[35; 39) | ||
46 | IDENT@[35; 39) "Item" | ||
47 | EQ@[39; 40) "=" | ||
48 | PATH_TYPE@[40; 43) | ||
49 | PATH@[40; 43) | ||
50 | PATH_SEGMENT@[40; 43) | ||
51 | NAME_REF@[40; 43) | ||
52 | IDENT@[40; 43) "u64" | ||
53 | R_ANGLE@[43; 44) ">" | ||
54 | SEMI@[44; 45) ";" | ||
55 | WHITESPACE@[45; 46) "\n" | ||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.rs b/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.rs new file mode 100644 index 000000000..cb0a105c2 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.rs | |||
@@ -0,0 +1 @@ | |||
impl<const N: u32> Bar<N> {} | |||
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.txt b/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.txt new file mode 100644 index 000000000..47fadef85 --- /dev/null +++ b/crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | SOURCE_FILE@[0; 29) | ||
2 | IMPL_BLOCK@[0; 28) | ||
3 | IMPL_KW@[0; 4) "impl" | ||
4 | TYPE_PARAM_LIST@[4; 18) | ||
5 | L_ANGLE@[4; 5) "<" | ||
6 | CONST_PARAM@[5; 17) | ||
7 | CONST_KW@[5; 10) "const" | ||
8 | WHITESPACE@[10; 11) " " | ||
9 | NAME@[11; 12) | ||
10 | IDENT@[11; 12) "N" | ||
11 | COLON@[12; 13) ":" | ||
12 | WHITESPACE@[13; 14) " " | ||
13 | PATH_TYPE@[14; 17) | ||
14 | PATH@[14; 17) | ||
15 | PATH_SEGMENT@[14; 17) | ||
16 | NAME_REF@[14; 17) | ||
17 | IDENT@[14; 17) "u32" | ||
18 | R_ANGLE@[17; 18) ">" | ||
19 | WHITESPACE@[18; 19) " " | ||
20 | PATH_TYPE@[19; 25) | ||
21 | PATH@[19; 25) | ||
22 | PATH_SEGMENT@[19; 25) | ||
23 | NAME_REF@[19; 22) | ||
24 | IDENT@[19; 22) "Bar" | ||
25 | TYPE_ARG_LIST@[22; 25) | ||
26 | L_ANGLE@[22; 23) "<" | ||
27 | TYPE_ARG@[23; 24) | ||
28 | PATH_TYPE@[23; 24) | ||
29 | PATH@[23; 24) | ||
30 | PATH_SEGMENT@[23; 24) | ||
31 | NAME_REF@[23; 24) | ||
32 | IDENT@[23; 24) "N" | ||
33 | R_ANGLE@[24; 25) ">" | ||
34 | WHITESPACE@[25; 26) " " | ||
35 | ITEM_LIST@[26; 28) | ||
36 | L_CURLY@[26; 27) "{" | ||
37 | R_CURLY@[27; 28) "}" | ||
38 | WHITESPACE@[28; 29) "\n" | ||