aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-08 17:26:38 +0100
committerAleksey Kladov <[email protected]>2018-08-08 17:31:44 +0100
commiteb8e9043e227682e6e7db2711091dc74d847e766 (patch)
tree5174136ad99ea4bd37f01c4c095c2976c6741403
parent8f21afacfc981e93f2ad78cd340e9b6c0e821d92 (diff)
Where clauses
-rw-r--r--src/grammar.ron1
-rw-r--r--src/grammar/type_params.rs60
-rw-r--r--src/grammar/types.rs2
-rw-r--r--src/syntax_kinds/generated.rs2
-rw-r--r--tests/data/parser/inline/0016_type_item_where_clause.txt17
-rw-r--r--tests/data/parser/inline/0056_trait_item.txt16
-rw-r--r--tests/data/parser/inline/0059_fn_item_where_clause.txt16
-rw-r--r--tests/data/parser/inline/0098_where_clause.rs6
-rw-r--r--tests/data/parser/inline/0098_where_clause.txt69
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
58fn 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
63pub(super) fn bounds_without_colon(p: &mut Parser) { 69pub(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// {}
86pub(super) fn where_clause(p: &mut Parser) { 99pub(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
117fn 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;
202fn path_type(p: &mut Parser) { 202pub(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 @@
1fn foo()
2where
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 @@
1FILE@[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)