about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs13
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs10
-rw-r--r--src/libsyntax/fold.rs15
-rw-r--r--src/libsyntax/parse/parser.rs121
-rw-r--r--src/libsyntax/print/pprust.rs11
-rw-r--r--src/libsyntax/visit.rs11
6 files changed, 119 insertions, 62 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index be8f32bc4d5..13ea5da66c8 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -415,18 +415,27 @@ pub struct WhereClause {
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum WherePredicate {
     BoundPredicate(WhereBoundPredicate),
+    RegionPredicate(WhereRegionPredicate),
     EqPredicate(WhereEqPredicate)
 }
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct WhereBoundPredicate {
-    pub id: NodeId,
     pub span: Span,
-    pub ident: Ident,
+    pub bounded_ty: P<Ty>,
     pub bounds: OwnedSlice<TyParamBound>,
 }
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
+pub struct WhereRegionPredicate {
+    pub span: Span,
+    pub lifetime: Lifetime,
+    pub bound: Lifetime
+}
+
+impl Copy for WhereRegionPredicate {}
+
+#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct WhereEqPredicate {
     pub id: NodeId,
     pub span: Span,
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index b31758e2d2a..c40ccaa31a5 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -426,12 +426,18 @@ impl<'a> TraitDef<'a> {
             match *clause {
                 ast::WherePredicate::BoundPredicate(ref wb) => {
                     ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                        id: ast::DUMMY_NODE_ID,
                         span: self.span,
-                        ident: wb.ident,
+                        bounded_ty: wb.bounded_ty.clone(),
                         bounds: OwnedSlice::from_vec(wb.bounds.iter().map(|b| b.clone()).collect())
                     })
                 }
+                ast::WherePredicate::RegionPredicate(ref rb) => {
+                    ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
+                        span: self.span,
+                        lifetime: rb.lifetime,
+                        bound: rb.bound
+                    })
+                }
                 ast::WherePredicate::EqPredicate(ref we) => {
                     ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
                         id: ast::DUMMY_NODE_ID,
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 10860ee5e01..dd1e8b73f36 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -814,17 +814,24 @@ pub fn noop_fold_where_predicate<T: Folder>(
                                  fld: &mut T)
                                  -> WherePredicate {
     match pred {
-        ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{id,
-                                                                     ident,
+        ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{bounded_ty,
                                                                      bounds,
                                                                      span}) => {
             ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
-                id: fld.new_id(id),
-                ident: fld.fold_ident(ident),
+                bounded_ty: fld.fold_ty(bounded_ty),
                 bounds: bounds.move_map(|x| fld.fold_ty_param_bound(x)),
                 span: fld.new_span(span)
             })
         }
+        ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{lifetime,
+                                                                       bound,
+                                                                       span}) => {
+            ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
+                span: fld.new_span(span),
+                lifetime: fld.fold_lifetime(lifetime),
+                bound: fld.fold_lifetime(bound)
+            })
+        }
         ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id,
                                                                path,
                                                                ty,
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
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index d2cc0cba317..d619a386664 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2437,12 +2437,19 @@ impl<'a> State<'a> {
             }
 
             match predicate {
-                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ident,
+                &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounded_ty,
                                                                               ref bounds,
                                                                               ..}) => {
-                    try!(self.print_ident(ident));
+                    try!(self.print_type(&**bounded_ty));
                     try!(self.print_bounds(":", bounds.as_slice()));
                 }
+                &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+                                                                                ref bound,
+                                                                                ..}) => {
+                    try!(self.print_lifetime(lifetime));
+                    try!(word(&mut self.s, ":"));
+                    try!(self.print_lifetime(bound));
+                }
                 &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{ref path, ref ty, ..}) => {
                     try!(self.print_path(path, false));
                     try!(space(&mut self.s));
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index b89e9a59349..c2a7a0316c7 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -583,13 +583,18 @@ pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics
     walk_lifetime_decls_helper(visitor, &generics.lifetimes);
     for predicate in generics.where_clause.predicates.iter() {
         match predicate {
-            &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{span,
-                                                                          ident,
+            &ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate{ref bounded_ty,
                                                                           ref bounds,
                                                                           ..}) => {
-                visitor.visit_ident(span, ident);
+                visitor.visit_ty(&**bounded_ty);
                 walk_ty_param_bounds_helper(visitor, bounds);
             }
+            &ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate{ref lifetime,
+                                                                            ref bound,
+                                                                            ..}) => {
+                visitor.visit_lifetime_ref(lifetime);
+                visitor.visit_lifetime_ref(bound);
+            }
             &ast::WherePredicate::EqPredicate(ast::WhereEqPredicate{id,
                                                                     ref path,
                                                                     ref ty,