aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/grammar')
-rw-r--r--crates/ra_syntax/src/grammar/type_params.rs45
1 files changed, 28 insertions, 17 deletions
diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs
index 7db25beba..1ec813b3e 100644
--- a/crates/ra_syntax/src/grammar/type_params.rs
+++ b/crates/ra_syntax/src/grammar/type_params.rs
@@ -104,22 +104,36 @@ 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 while is_where_predicate(p) {
109 || p.current() == LIFETIME 109 where_predicate(p);
110 || p.current() == FOR_KW 110
111 || p.current() == L_ANGLE) 111 let comma = p.eat(COMMA);
112 { 112
113 if is_where_clause_end(p) {
113 break; 114 break;
114 } 115 }
115 where_predicate(p); 116
116 if p.current() != L_CURLY && p.current() != SEMI && p.current() != EQ { 117 if !comma {
117 p.expect(COMMA); 118 p.error("expected comma");
118 } 119 }
119 } 120 }
121
120 m.complete(p, WHERE_CLAUSE); 122 m.complete(p, WHERE_CLAUSE);
121} 123}
122 124
125fn is_where_predicate(p: &mut Parser) -> bool {
126 match p.current() {
127 LIFETIME => true,
128 IMPL_KW => false,
129 token => types::TYPE_FIRST.contains(token),
130 }
131}
132
133fn is_where_clause_end(p: &mut Parser) -> bool {
134 p.current() == L_CURLY || p.current() == SEMI || p.current() == EQ
135}
136
123fn where_predicate(p: &mut Parser) { 137fn where_predicate(p: &mut Parser) {
124 let m = p.start(); 138 let m = p.start();
125 match p.current() { 139 match p.current() {
@@ -131,20 +145,17 @@ fn where_predicate(p: &mut Parser) {
131 p.error("expected colon"); 145 p.error("expected colon");
132 } 146 }
133 } 147 }
148 IMPL_KW => {
149 p.error("expected lifetime or type");
150 }
134 _ => { 151 _ => {
135 // test where_pred_for 152 // test where_pred_for
136 // fn test<F>() 153 // fn test<F>()
137 // where 154 // where
138 // for<'a> F: Fn(&'a str) 155 // for<'a> F: Fn(&'a str)
139 // { } 156 // { }
140 if p.at(FOR_KW) { 157 types::type_(p);
141 types::for_binder(p); 158
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) { 159 if p.at(COLON) {
149 bounds(p); 160 bounds(p);
150 } else { 161 } else {