Allow types to the left of : in where predicates.
@@ -104,22 +104,32 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
}
let m = p.start();
p.bump();
+
+ if is_where_clause_end(p) {
+ // Empty where clause
+ } else {
loop {
- if !(paths::is_path_start(p)
- || p.current() == LIFETIME
- || p.current() == FOR_KW
- || p.current() == L_ANGLE)
- {
+ where_predicate(p);
+
+ let comma = p.eat(COMMA);
+
+ if is_where_clause_end(p) {
break;
}
- where_predicate(p);
- if p.current() != L_CURLY && p.current() != SEMI && p.current() != EQ {
- p.expect(COMMA);
+
+ if !comma {
+ p.error("expected comma")
+ }
}
}
+
m.complete(p, WHERE_CLAUSE);
}
+fn is_where_clause_end(p: &mut Parser) -> bool {
+ p.current() == L_CURLY || p.current() == SEMI || p.current() == EQ
+}
+
fn where_predicate(p: &mut Parser) {
let m = p.start();
match p.current() {
@@ -131,20 +141,13 @@ fn where_predicate(p: &mut Parser) {
p.error("expected colon");
}
}
- _ => {
- // test where_pred_for
- // fn test<F>()
- // where
- // for<'a> F: Fn(&'a str)
- // { }
- if p.at(FOR_KW) {
- types::for_binder(p);
- }
- if paths::is_path_start(p) || p.at(L_ANGLE) {
- types::path_type_(p, false);
- } else {
- p.error("expected a type");
+ IMPL_KW => {
+ p.error("expected lifetime or type");
+ return;
}
+ _ => {
+ types::type_(p);
+
if p.at(COLON) {
bounds(p);
} else {
