aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
authorErlend Tobiassen <[email protected]>2019-01-22 00:11:35 +0000
committerErlend Tobiassen <[email protected]>2019-01-22 00:11:35 +0000
commit1059ec74e2147559b43aab9b12f84849319910cc (patch)
tree77ba85c6121f341e017d2b038866b8c172fa28d5 /crates/ra_syntax
parentb59334e67a3c76c91ccd7bc1212a485ab0ac4065 (diff)
Allow types to the left of : in where predicates.
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/src/grammar/type_params.rs51
1 files changed, 27 insertions, 24 deletions
diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs
index 7db25beba..fe9dba2ae 100644
--- a/crates/ra_syntax/src/grammar/type_params.rs
+++ b/crates/ra_syntax/src/grammar/type_params.rs
@@ -104,22 +104,32 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
104 } 104 }
105 let m = p.start(); 105 let m = p.start();
106 p.bump(); 106 p.bump();
107 loop { 107
108 if !(paths::is_path_start(p) 108 if is_where_clause_end(p) {
109 || p.current() == LIFETIME 109 // Empty where clause
110 || p.current() == FOR_KW 110 } else {
111 || p.current() == L_ANGLE) 111 loop {
112 { 112 where_predicate(p);
113 break; 113
114 } 114 let comma = p.eat(COMMA);
115 where_predicate(p); 115
116 if p.current() != L_CURLY && p.current() != SEMI && p.current() != EQ { 116 if is_where_clause_end(p) {
117 p.expect(COMMA); 117 break;
118 }
119
120 if !comma {
121 p.error("expected comma")
122 }
118 } 123 }
119 } 124 }
125
120 m.complete(p, WHERE_CLAUSE); 126 m.complete(p, WHERE_CLAUSE);
121} 127}
122 128
129fn is_where_clause_end(p: &mut Parser) -> bool {
130 p.current() == L_CURLY || p.current() == SEMI || p.current() == EQ
131}
132
123fn where_predicate(p: &mut Parser) { 133fn where_predicate(p: &mut Parser) {
124 let m = p.start(); 134 let m = p.start();
125 match p.current() { 135 match p.current() {
@@ -131,20 +141,13 @@ fn where_predicate(p: &mut Parser) {
131 p.error("expected colon"); 141 p.error("expected colon");
132 } 142 }
133 } 143 }
144 IMPL_KW => {
145 p.error("expected lifetime or type");
146 return;
147 }
134 _ => { 148 _ => {
135 // test where_pred_for 149 types::type_(p);
136 // fn test<F>() 150
137 // where
138 // for<'a> F: Fn(&'a str)
139 // { }
140 if p.at(FOR_KW) {
141 types::for_binder(p);
142 }
143 if paths::is_path_start(p) || p.at(L_ANGLE) {
144 types::path_type_(p, false);
145 } else {
146 p.error("expected a type");
147 }
148 if p.at(COLON) { 151 if p.at(COLON) {
149 bounds(p); 152 bounds(p);
150 } else { 153 } else {