aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-01-06 23:43:24 +0000
committerGitHub <[email protected]>2020-01-06 23:43:24 +0000
commit7b9df1062d65e6977f16d6595ffb5912769011a3 (patch)
tree8a9535261dac04f171caa68d4b908cdde0b4a34c
parentc92a090f49cad2fa540562536f07fcb619f16680 (diff)
parentce1b34fd59a6145a4bb5682d672c846e101725d4 (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]>
-rw-r--r--crates/ra_parser/src/grammar/items/traits.rs5
-rw-r--r--crates/ra_parser/src/grammar/type_args.rs10
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs1
-rw-r--r--crates/ra_syntax/src/ast/generated.rs33
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt51
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.txt38
-rw-r--r--xtask/src/ast_src.rs3
9 files changed, 123 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> {}
103fn choose_type_params_over_qpath(p: &Parser) -> bool { 105fn 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>;
30fn type_arg(p: &mut Parser) { 30fn 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)]
3119pub struct TypeArg { 3122pub struct TypeArg {
@@ -3196,6 +3199,36 @@ impl AstNode for LifetimeArg {
3196} 3199}
3197impl LifetimeArg {} 3200impl LifetimeArg {}
3198#[derive(Debug, Clone, PartialEq, Eq, Hash)] 3201#[derive(Debug, Clone, PartialEq, Eq, Hash)]
3202pub struct ConstArg {
3203 pub(crate) syntax: SyntaxNode,
3204}
3205impl 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}
3223impl 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)]
3199pub struct MacroItems { 3232pub 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 @@
1SOURCE_FILE@[0; 36) 1SOURCE_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 @@
1SOURCE_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"
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index d494a4a38..67d1f41bc 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -206,6 +206,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
206 "LIFETIME_ARG", 206 "LIFETIME_ARG",
207 "TYPE_ARG", 207 "TYPE_ARG",
208 "ASSOC_TYPE_ARG", 208 "ASSOC_TYPE_ARG",
209 "CONST_ARG",
209 "PARAM_LIST", 210 "PARAM_LIST",
210 "PARAM", 211 "PARAM",
211 "SELF_PARAM", 212 "SELF_PARAM",
@@ -511,10 +512,12 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
511 type_args: [TypeArg], 512 type_args: [TypeArg],
512 lifetime_args: [LifetimeArg], 513 lifetime_args: [LifetimeArg],
513 assoc_type_args: [AssocTypeArg], 514 assoc_type_args: [AssocTypeArg],
515 const_arg: [ConstArg],
514 } 516 }
515 struct TypeArg { TypeRef } 517 struct TypeArg { TypeRef }
516 struct AssocTypeArg { NameRef, TypeRef } 518 struct AssocTypeArg { NameRef, TypeRef }
517 struct LifetimeArg {} 519 struct LifetimeArg {}
520 struct ConstArg { Literal, BlockExpr }
518 521
519 struct MacroItems: ModuleItemOwner, FnDefOwner { } 522 struct MacroItems: ModuleItemOwner, FnDefOwner { }
520 523