diff options
author | Aleksey Kladov <[email protected]> | 2018-08-08 17:26:38 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-08 17:31:44 +0100 |
commit | eb8e9043e227682e6e7db2711091dc74d847e766 (patch) | |
tree | 5174136ad99ea4bd37f01c4c095c2976c6741403 | |
parent | 8f21afacfc981e93f2ad78cd340e9b6c0e821d92 (diff) |
Where clauses
-rw-r--r-- | src/grammar.ron | 1 | ||||
-rw-r--r-- | src/grammar/type_params.rs | 60 | ||||
-rw-r--r-- | src/grammar/types.rs | 2 | ||||
-rw-r--r-- | src/syntax_kinds/generated.rs | 2 | ||||
-rw-r--r-- | tests/data/parser/inline/0016_type_item_where_clause.txt | 17 | ||||
-rw-r--r-- | tests/data/parser/inline/0056_trait_item.txt | 16 | ||||
-rw-r--r-- | tests/data/parser/inline/0059_fn_item_where_clause.txt | 16 | ||||
-rw-r--r-- | tests/data/parser/inline/0098_where_clause.rs | 6 | ||||
-rw-r--r-- | tests/data/parser/inline/0098_where_clause.txt | 69 |
9 files changed, 162 insertions, 27 deletions
diff --git a/src/grammar.ron b/src/grammar.ron index df1dfe050..0443dd798 100644 --- a/src/grammar.ron +++ b/src/grammar.ron | |||
@@ -192,6 +192,7 @@ Grammar( | |||
192 | "ALIAS", | 192 | "ALIAS", |
193 | "VISIBILITY", | 193 | "VISIBILITY", |
194 | "WHERE_CLAUSE", | 194 | "WHERE_CLAUSE", |
195 | "WHERE_PRED", | ||
195 | "ABI", | 196 | "ABI", |
196 | "NAME", | 197 | "NAME", |
197 | "NAME_REF", | 198 | "NAME_REF", |
diff --git a/src/grammar/type_params.rs b/src/grammar/type_params.rs index 1227482ad..0a3e8fd07 100644 --- a/src/grammar/type_params.rs +++ b/src/grammar/type_params.rs | |||
@@ -24,13 +24,8 @@ pub(super) fn type_param_list(p: &mut Parser) { | |||
24 | assert!(p.at(LIFETIME)); | 24 | assert!(p.at(LIFETIME)); |
25 | let m = p.start(); | 25 | let m = p.start(); |
26 | p.bump(); | 26 | p.bump(); |
27 | if p.eat(COLON) { | 27 | if p.at(COLON) { |
28 | while p.at(LIFETIME) { | 28 | lifetime_bounds(p); |
29 | p.bump(); | ||
30 | if !p.eat(PLUS) { | ||
31 | break; | ||
32 | } | ||
33 | } | ||
34 | } | 29 | } |
35 | m.complete(p, LIFETIME_PARAM); | 30 | m.complete(p, LIFETIME_PARAM); |
36 | } | 31 | } |
@@ -60,6 +55,17 @@ pub(super) fn bounds(p: &mut Parser) { | |||
60 | bounds_without_colon(p); | 55 | bounds_without_colon(p); |
61 | } | 56 | } |
62 | 57 | ||
58 | fn lifetime_bounds(p: &mut Parser) { | ||
59 | assert!(p.at(COLON)); | ||
60 | p.bump(); | ||
61 | while p.at(LIFETIME) { | ||
62 | p.bump(); | ||
63 | if !p.eat(PLUS) { | ||
64 | break; | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
63 | pub(super) fn bounds_without_colon(p: &mut Parser) { | 69 | pub(super) fn bounds_without_colon(p: &mut Parser) { |
64 | loop { | 70 | loop { |
65 | let has_paren = p.eat(L_PAREN); | 71 | let has_paren = p.eat(L_PAREN); |
@@ -83,13 +89,39 @@ pub(super) fn bounds_without_colon(p: &mut Parser) { | |||
83 | } | 89 | } |
84 | } | 90 | } |
85 | 91 | ||
92 | // test where_clause | ||
93 | // fn foo() | ||
94 | // where | ||
95 | // 'a: 'b + 'c, | ||
96 | // T: Clone + Copy + 'static, | ||
97 | // Iterator::Item: 'a, | ||
98 | // {} | ||
86 | pub(super) fn where_clause(p: &mut Parser) { | 99 | pub(super) fn where_clause(p: &mut Parser) { |
87 | if p.at(WHERE_KW) { | 100 | if !p.at(WHERE_KW) { |
88 | let m = p.start(); | 101 | return; |
89 | p.bump(); | 102 | } |
90 | p.expect(IDENT); | 103 | let m = p.start(); |
91 | p.expect(COLON); | 104 | p.bump(); |
92 | p.expect(IDENT); | 105 | loop { |
93 | m.complete(p, WHERE_CLAUSE); | 106 | if !(paths::is_path_start(p) || p.current() == LIFETIME) { |
107 | break | ||
108 | } | ||
109 | where_predicate(p); | ||
110 | if p.current() != L_CURLY && p.current() != SEMI { | ||
111 | p.expect(COMMA); | ||
112 | } | ||
113 | } | ||
114 | m.complete(p, WHERE_CLAUSE); | ||
115 | } | ||
116 | |||
117 | fn where_predicate(p: &mut Parser) { | ||
118 | let m = p.start(); | ||
119 | if p.at(LIFETIME) { | ||
120 | p.eat(LIFETIME); | ||
121 | lifetime_bounds(p) | ||
122 | } else { | ||
123 | types::path_type(p); | ||
124 | bounds(p); | ||
94 | } | 125 | } |
126 | m.complete(p, WHERE_PRED); | ||
95 | } | 127 | } |
diff --git a/src/grammar/types.rs b/src/grammar/types.rs index c8ced3d28..0d8c6bfba 100644 --- a/src/grammar/types.rs +++ b/src/grammar/types.rs | |||
@@ -199,7 +199,7 @@ fn impl_trait_type(p: &mut Parser) { | |||
199 | // type B = ::Foo; | 199 | // type B = ::Foo; |
200 | // type C = self::Foo; | 200 | // type C = self::Foo; |
201 | // type D = super::Foo; | 201 | // type D = super::Foo; |
202 | fn path_type(p: &mut Parser) { | 202 | pub(super) fn path_type(p: &mut Parser) { |
203 | assert!(paths::is_path_start(p)); | 203 | assert!(paths::is_path_start(p)); |
204 | let m = p.start(); | 204 | let m = p.start(); |
205 | paths::type_path(p); | 205 | paths::type_path(p); |
diff --git a/src/syntax_kinds/generated.rs b/src/syntax_kinds/generated.rs index a74acf6eb..9a9c1f223 100644 --- a/src/syntax_kinds/generated.rs +++ b/src/syntax_kinds/generated.rs | |||
@@ -175,6 +175,7 @@ pub enum SyntaxKind { | |||
175 | ALIAS, | 175 | ALIAS, |
176 | VISIBILITY, | 176 | VISIBILITY, |
177 | WHERE_CLAUSE, | 177 | WHERE_CLAUSE, |
178 | WHERE_PRED, | ||
178 | ABI, | 179 | ABI, |
179 | NAME, | 180 | NAME, |
180 | NAME_REF, | 181 | NAME_REF, |
@@ -415,6 +416,7 @@ impl SyntaxKind { | |||
415 | ALIAS => &SyntaxInfo { name: "ALIAS" }, | 416 | ALIAS => &SyntaxInfo { name: "ALIAS" }, |
416 | VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, | 417 | VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, |
417 | WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, | 418 | WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, |
419 | WHERE_PRED => &SyntaxInfo { name: "WHERE_PRED" }, | ||
418 | ABI => &SyntaxInfo { name: "ABI" }, | 420 | ABI => &SyntaxInfo { name: "ABI" }, |
419 | NAME => &SyntaxInfo { name: "NAME" }, | 421 | NAME => &SyntaxInfo { name: "NAME" }, |
420 | NAME_REF => &SyntaxInfo { name: "NAME_REF" }, | 422 | NAME_REF => &SyntaxInfo { name: "NAME_REF" }, |
diff --git a/tests/data/parser/inline/0016_type_item_where_clause.txt b/tests/data/parser/inline/0016_type_item_where_clause.txt index 5879edc42..2f3c52960 100644 --- a/tests/data/parser/inline/0016_type_item_where_clause.txt +++ b/tests/data/parser/inline/0016_type_item_where_clause.txt | |||
@@ -8,10 +8,19 @@ FILE@[0; 31) | |||
8 | WHERE_CLAUSE@[9; 24) | 8 | WHERE_CLAUSE@[9; 24) |
9 | WHERE_KW@[9; 14) | 9 | WHERE_KW@[9; 14) |
10 | WHITESPACE@[14; 15) | 10 | WHITESPACE@[14; 15) |
11 | IDENT@[15; 18) "Foo" | 11 | WHERE_PRED@[15; 24) |
12 | COLON@[18; 19) | 12 | PATH_TYPE@[15; 18) |
13 | WHITESPACE@[19; 20) | 13 | PATH@[15; 18) |
14 | IDENT@[20; 24) "Copy" | 14 | PATH_SEGMENT@[15; 18) |
15 | NAME_REF@[15; 18) | ||
16 | IDENT@[15; 18) "Foo" | ||
17 | COLON@[18; 19) | ||
18 | WHITESPACE@[19; 20) | ||
19 | PATH@[20; 24) | ||
20 | PATH_SEGMENT@[20; 24) | ||
21 | NAME_REF@[20; 24) | ||
22 | IDENT@[20; 24) "Copy" | ||
23 | err: `expected COMMA` | ||
15 | WHITESPACE@[24; 25) | 24 | WHITESPACE@[24; 25) |
16 | EQ@[25; 26) | 25 | EQ@[25; 26) |
17 | WHITESPACE@[26; 27) | 26 | WHITESPACE@[26; 27) |
diff --git a/tests/data/parser/inline/0056_trait_item.txt b/tests/data/parser/inline/0056_trait_item.txt index b2d36afe7..ba4e0ebc8 100644 --- a/tests/data/parser/inline/0056_trait_item.txt +++ b/tests/data/parser/inline/0056_trait_item.txt | |||
@@ -27,10 +27,18 @@ FILE@[0; 42) | |||
27 | WHERE_CLAUSE@[25; 38) | 27 | WHERE_CLAUSE@[25; 38) |
28 | WHERE_KW@[25; 30) | 28 | WHERE_KW@[25; 30) |
29 | WHITESPACE@[30; 31) | 29 | WHITESPACE@[30; 31) |
30 | IDENT@[31; 32) "U" | 30 | WHERE_PRED@[31; 38) |
31 | COLON@[32; 33) | 31 | PATH_TYPE@[31; 32) |
32 | WHITESPACE@[33; 34) | 32 | PATH@[31; 32) |
33 | IDENT@[34; 38) "Copy" | 33 | PATH_SEGMENT@[31; 32) |
34 | NAME_REF@[31; 32) | ||
35 | IDENT@[31; 32) "U" | ||
36 | COLON@[32; 33) | ||
37 | WHITESPACE@[33; 34) | ||
38 | PATH@[34; 38) | ||
39 | PATH_SEGMENT@[34; 38) | ||
40 | NAME_REF@[34; 38) | ||
41 | IDENT@[34; 38) "Copy" | ||
34 | WHITESPACE@[38; 39) | 42 | WHITESPACE@[38; 39) |
35 | L_CURLY@[39; 40) | 43 | L_CURLY@[39; 40) |
36 | R_CURLY@[40; 41) | 44 | R_CURLY@[40; 41) |
diff --git a/tests/data/parser/inline/0059_fn_item_where_clause.txt b/tests/data/parser/inline/0059_fn_item_where_clause.txt index 8614d1597..afedf983e 100644 --- a/tests/data/parser/inline/0059_fn_item_where_clause.txt +++ b/tests/data/parser/inline/0059_fn_item_where_clause.txt | |||
@@ -17,10 +17,18 @@ FILE@[0; 29) | |||
17 | WHERE_CLAUSE@[12; 25) | 17 | WHERE_CLAUSE@[12; 25) |
18 | WHERE_KW@[12; 17) | 18 | WHERE_KW@[12; 17) |
19 | WHITESPACE@[17; 18) | 19 | WHITESPACE@[17; 18) |
20 | IDENT@[18; 19) "T" | 20 | WHERE_PRED@[18; 25) |
21 | COLON@[19; 20) | 21 | PATH_TYPE@[18; 19) |
22 | WHITESPACE@[20; 21) | 22 | PATH@[18; 19) |
23 | IDENT@[21; 25) "Copy" | 23 | PATH_SEGMENT@[18; 19) |
24 | NAME_REF@[18; 19) | ||
25 | IDENT@[18; 19) "T" | ||
26 | COLON@[19; 20) | ||
27 | WHITESPACE@[20; 21) | ||
28 | PATH@[21; 25) | ||
29 | PATH_SEGMENT@[21; 25) | ||
30 | NAME_REF@[21; 25) | ||
31 | IDENT@[21; 25) "Copy" | ||
24 | WHITESPACE@[25; 26) | 32 | WHITESPACE@[25; 26) |
25 | BLOCK_EXPR@[26; 28) | 33 | BLOCK_EXPR@[26; 28) |
26 | L_CURLY@[26; 27) | 34 | L_CURLY@[26; 27) |
diff --git a/tests/data/parser/inline/0098_where_clause.rs b/tests/data/parser/inline/0098_where_clause.rs new file mode 100644 index 000000000..592a005f9 --- /dev/null +++ b/tests/data/parser/inline/0098_where_clause.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() | ||
2 | where | ||
3 | 'a: 'b + 'c, | ||
4 | T: Clone + Copy + 'static, | ||
5 | Iterator::Item: 'a, | ||
6 | {} | ||
diff --git a/tests/data/parser/inline/0098_where_clause.txt b/tests/data/parser/inline/0098_where_clause.txt new file mode 100644 index 000000000..a1180b554 --- /dev/null +++ b/tests/data/parser/inline/0098_where_clause.txt | |||
@@ -0,0 +1,69 @@ | |||
1 | FILE@[0; 87) | ||
2 | FN_ITEM@[0; 86) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | WHERE_CLAUSE@[9; 83) | ||
12 | WHERE_KW@[9; 14) | ||
13 | WHITESPACE@[14; 18) | ||
14 | WHERE_PRED@[18; 29) | ||
15 | LIFETIME@[18; 20) "'a" | ||
16 | COLON@[20; 21) | ||
17 | WHITESPACE@[21; 22) | ||
18 | LIFETIME@[22; 24) "'b" | ||
19 | WHITESPACE@[24; 25) | ||
20 | PLUS@[25; 26) | ||
21 | WHITESPACE@[26; 27) | ||
22 | LIFETIME@[27; 29) "'c" | ||
23 | COMMA@[29; 30) | ||
24 | WHITESPACE@[30; 34) | ||
25 | WHERE_PRED@[34; 59) | ||
26 | PATH_TYPE@[34; 35) | ||
27 | PATH@[34; 35) | ||
28 | PATH_SEGMENT@[34; 35) | ||
29 | NAME_REF@[34; 35) | ||
30 | IDENT@[34; 35) "T" | ||
31 | COLON@[35; 36) | ||
32 | WHITESPACE@[36; 37) | ||
33 | PATH@[37; 42) | ||
34 | PATH_SEGMENT@[37; 42) | ||
35 | NAME_REF@[37; 42) | ||
36 | IDENT@[37; 42) "Clone" | ||
37 | WHITESPACE@[42; 43) | ||
38 | PLUS@[43; 44) | ||
39 | WHITESPACE@[44; 45) | ||
40 | PATH@[45; 49) | ||
41 | PATH_SEGMENT@[45; 49) | ||
42 | NAME_REF@[45; 49) | ||
43 | IDENT@[45; 49) "Copy" | ||
44 | WHITESPACE@[49; 50) | ||
45 | PLUS@[50; 51) | ||
46 | WHITESPACE@[51; 52) | ||
47 | LIFETIME@[52; 59) "'static" | ||
48 | COMMA@[59; 60) | ||
49 | WHITESPACE@[60; 64) | ||
50 | WHERE_PRED@[64; 82) | ||
51 | PATH_TYPE@[64; 78) | ||
52 | PATH@[64; 78) | ||
53 | PATH@[64; 72) | ||
54 | PATH_SEGMENT@[64; 72) | ||
55 | NAME_REF@[64; 72) | ||
56 | IDENT@[64; 72) "Iterator" | ||
57 | COLONCOLON@[72; 74) | ||
58 | PATH_SEGMENT@[74; 78) | ||
59 | NAME_REF@[74; 78) | ||
60 | IDENT@[74; 78) "Item" | ||
61 | COLON@[78; 79) | ||
62 | WHITESPACE@[79; 80) | ||
63 | LIFETIME@[80; 82) "'a" | ||
64 | COMMA@[82; 83) | ||
65 | WHITESPACE@[83; 84) | ||
66 | BLOCK_EXPR@[84; 86) | ||
67 | L_CURLY@[84; 85) | ||
68 | R_CURLY@[85; 86) | ||
69 | WHITESPACE@[86; 87) | ||