about summary refs log tree commit diff
path: root/src/libsyntax/parse/parser.rs
diff options
context:
space:
mode:
authorJared Roesch <roeschinc@gmail.com>2014-12-20 02:29:19 -0800
committerJared Roesch <roeschinc@gmail.com>2014-12-20 02:48:17 -0800
commite0cac488ac6ca16507da390429565b7879f76bb4 (patch)
tree04e303a6337ac139698b9eecee0e2f52418d04d2 /src/libsyntax/parse/parser.rs
parent8f51ad2420776925c12be67a7bf38ac28343fd1f (diff)
downloadrust-e0cac488ac6ca16507da390429565b7879f76bb4.tar.gz
rust-e0cac488ac6ca16507da390429565b7879f76bb4.zip
Add parser support for generalized where clauses
Implement support in the parser for generalized where clauses,
as well as the conversion of ast::WherePredicates to
ty::Predicate in `collect.rs`.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
-rw-r--r--src/libsyntax/parse/parser.rs121
1 files changed, 72 insertions, 49 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 3ad224b93ce..64bcf7dbdd1 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -1497,9 +1497,6 @@ impl<'a> Parser<'a> {
     }
 
     /// Parse a type.
-    ///
-    /// The second parameter specifies whether the `+` binary operator is
-    /// allowed in the type grammar.
     pub fn parse_ty(&mut self) -> P<Ty> {
         maybe_whole!(no_clone self, NtTy);
 
@@ -4179,6 +4176,10 @@ impl<'a> Parser<'a> {
     }
 
     /// Parses an optional `where` clause and places it in `generics`.
+    ///
+    /// ```
+    /// where T : Trait<U, V> + 'b, 'a : 'b
+    /// ```
     fn parse_where_clause(&mut self, generics: &mut ast::Generics) {
         if !self.eat_keyword(keywords::Where) {
             return
@@ -4187,58 +4188,80 @@ impl<'a> Parser<'a> {
         let mut parsed_something = false;
         loop {
             let lo = self.span.lo;
-            let path = match self.token {
-                token::Ident(..) => self.parse_path(NoTypesAllowed),
-                _ => break,
-            };
+            match self.token {
+                token::OpenDelim(token::Brace) => {
+                    break
+                }
 
-            if self.eat(&token::Colon) {
-                let bounds = self.parse_ty_param_bounds();
-                let hi = self.span.hi;
-                let span = mk_sp(lo, hi);
+                token::Lifetime(..) => {
+                    let bounded_lifetime =
+                        self.parse_lifetime();
 
-                if bounds.len() == 0 {
-                    self.span_err(span,
-                                  "each predicate in a `where` clause must have \
-                                   at least one bound in it");
+                    self.eat(&token::Colon);
+
+                    // FIXME(#20049)
+                    let bounding_lifetime =
+                        self.parse_lifetime();
+
+                    let hi = self.span.hi;
+                    let span = mk_sp(lo, hi);
+
+                    generics.where_clause.predicates.push(ast::WherePredicate::RegionPredicate(
+                        ast::WhereRegionPredicate {
+                            span: span,
+                            lifetime: bounded_lifetime,
+                            bound: bounding_lifetime
+                        }
+                    ));
+
+                    parsed_something = true;
                 }
 
-                let ident = match ast_util::path_to_ident(&path) {
-                    Some(ident) => ident,
-                    None => {
-                        self.span_err(path.span, "expected a single identifier \
-                                                  in bound where clause");
-                        break;
-                    }
-                };
+                _ => {
+                    let bounded_ty = self.parse_ty();
 
-                generics.where_clause.predicates.push(
-                    ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                        id: ast::DUMMY_NODE_ID,
-                        span: span,
-                        ident: ident,
-                        bounds: bounds,
-                }));
-                parsed_something = true;
-            } else if self.eat(&token::Eq) {
-                let ty = self.parse_ty();
-                let hi = self.span.hi;
-                let span = mk_sp(lo, hi);
-                generics.where_clause.predicates.push(
-                    ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
-                        id: ast::DUMMY_NODE_ID,
-                        span: span,
-                        path: path,
-                        ty: ty,
-                }));
-                parsed_something = true;
-                // FIXME(#18433)
-                self.span_err(span, "equality constraints are not yet supported in where clauses");
-            } else {
-                let last_span = self.last_span;
-                self.span_err(last_span,
+                    if self.eat(&token::Colon) {
+                        let bounds = self.parse_ty_param_bounds();
+                        let hi = self.span.hi;
+                        let span = mk_sp(lo, hi);
+
+                        if bounds.len() == 0 {
+                            self.span_err(span,
+                                          "each predicate in a `where` clause must have \
+                                   at least one bound in it");
+                        }
+
+                        generics.where_clause.predicates.push(ast::WherePredicate::BoundPredicate(
+                                ast::WhereBoundPredicate {
+                                    span: span,
+                                    bounded_ty: bounded_ty,
+                                    bounds: bounds,
+                        }));
+
+                        parsed_something = true;
+                    } else if self.eat(&token::Eq) {
+                        // let ty = self.parse_ty();
+                        let hi = self.span.hi;
+                        let span = mk_sp(lo, hi);
+                        // generics.where_clause.predicates.push(
+                        //     ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
+                        //         id: ast::DUMMY_NODE_ID,
+                        //         span: span,
+                        //         path: panic!("NYI"), //bounded_ty,
+                        //         ty: ty,
+                        // }));
+                        // parsed_something = true;
+                        // // FIXME(#18433)
+                        self.span_err(span,
+                                     "equality constraints are not yet supported \
+                                     in where clauses (#20041)");
+                    } else {
+                        let last_span = self.last_span;
+                        self.span_err(last_span,
                               "unexpected token in `where` clause");
-            }
+                    }
+                }
+            };
 
             if !self.eat(&token::Comma) {
                 break