diff options
| author | Jared Roesch <roeschinc@gmail.com> | 2014-12-20 02:29:19 -0800 |
|---|---|---|
| committer | Jared Roesch <roeschinc@gmail.com> | 2014-12-20 02:48:17 -0800 |
| commit | e0cac488ac6ca16507da390429565b7879f76bb4 (patch) | |
| tree | 04e303a6337ac139698b9eecee0e2f52418d04d2 /src/libsyntax/parse/parser.rs | |
| parent | 8f51ad2420776925c12be67a7bf38ac28343fd1f (diff) | |
| download | rust-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.rs | 121 |
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 |
