aboutsummaryrefslogtreecommitdiff
path: root/src/grammar
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 /src/grammar
parent8f21afacfc981e93f2ad78cd340e9b6c0e821d92 (diff)
Where clauses
Diffstat (limited to 'src/grammar')
-rw-r--r--src/grammar/type_params.rs60
-rw-r--r--src/grammar/types.rs2
2 files changed, 47 insertions, 15 deletions
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);