diff options
| author | bors <bors@rust-lang.org> | 2014-12-20 16:12:37 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-12-20 16:12:37 +0000 |
| commit | 8a33de89c4a7acf04a2f3fa5d6ba4aa3fe3f8dc0 (patch) | |
| tree | f9a55b4c52e9051f3742da588b500d1b34ba398d /src/libsyntax/parse/parser.rs | |
| parent | f8f2c7a9537c7f333b242f616aefb75a83860927 (diff) | |
| parent | acd31db22938968929913b54779cb33a3c2e03df (diff) | |
| download | rust-8a33de89c4a7acf04a2f3fa5d6ba4aa3fe3f8dc0.tar.gz rust-8a33de89c4a7acf04a2f3fa5d6ba4aa3fe3f8dc0.zip | |
auto merge of #20073 : nikomatsakis/rust/generalized-where-clause-parser, r=nikomatsakis
This is the same branch as #20002 but with the pretty-printing test fixed.
Diffstat (limited to 'src/libsyntax/parse/parser.rs')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 120 |
1 files changed, 71 insertions, 49 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3ad224b93ce..f8b47e0405f 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,79 @@ 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); + + let bounds = + self.parse_lifetimes(token::BinOp(token::Plus)); + + 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, + bounds: bounds + } + )); + + 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 |
