From 1059ec74e2147559b43aab9b12f84849319910cc Mon Sep 17 00:00:00 2001
From: Erlend Tobiassen <erlend.tobiassen@gmail.com>
Date: Tue, 22 Jan 2019 01:11:35 +0100
Subject: [PATCH] Allow types to the left of : in where predicates.

---
 crates/ra_syntax/src/grammar/type_params.rs | 51 +++++++++++----------
 1 file 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 7db25bebad..fe9dba2ae4 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) {
     }
     let m = p.start();
     p.bump();
-    loop {
-        if !(paths::is_path_start(p)
-            || p.current() == LIFETIME
-            || p.current() == FOR_KW
-            || p.current() == L_ANGLE)
-        {
-            break;
-        }
-        where_predicate(p);
-        if p.current() != L_CURLY && p.current() != SEMI && p.current() != EQ {
-            p.expect(COMMA);
+
+    if is_where_clause_end(p) {
+        // Empty where clause
+    } else {
+        loop {
+            where_predicate(p);
+
+            let comma = p.eat(COMMA);
+
+            if is_where_clause_end(p) {
+                break;
+            }
+
+            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");
             }
         }
+        IMPL_KW => {
+            p.error("expected lifetime or type");
+            return;
+        }
         _ => {
-            // 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");
-            }
+            types::type_(p);
+
             if p.at(COLON) {
                 bounds(p);
             } else {