diff options
Diffstat (limited to 'src/grammar')
-rw-r--r-- | src/grammar/type_params.rs | 60 | ||||
-rw-r--r-- | src/grammar/types.rs | 2 |
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 | ||
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); |