diff options
| author | bors <bors@rust-lang.org> | 2017-03-14 10:40:09 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-03-14 10:40:09 +0000 |
| commit | 6f10e2f63de720468e2b4bfcb275e4b90b1f9870 (patch) | |
| tree | 11f51d7f07c5a74ab22e20b7f3556c4c0191fe66 /src/libsyntax/parse | |
| parent | fa53235cc4364fe085ccba720237d19b669c2f8b (diff) | |
| parent | b1aa99352a69e328094e096bbbd1741b68c0667f (diff) | |
| download | rust-6f10e2f63de720468e2b4bfcb275e4b90b1f9870.tar.gz rust-6f10e2f63de720468e2b4bfcb275e4b90b1f9870.zip | |
Auto merge of #39921 - cramertj:add-catch-to-ast, r=nikomatsakis
Add catch {} to AST
Part of #39849. Builds on #39864.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 27 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 1 |
2 files changed, 28 insertions, 0 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ff7918cc278..8f66c1a2b8c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2280,6 +2280,12 @@ impl<'a> Parser<'a> { BlockCheckMode::Unsafe(ast::UserProvided), attrs); } + if self.is_catch_expr() { + assert!(self.eat_keyword(keywords::Do)); + assert!(self.eat_keyword(keywords::Catch)); + let lo = self.prev_span.lo; + return self.parse_catch_expr(lo, attrs); + } if self.eat_keyword(keywords::Return) { if self.token.can_begin_expr() { let e = self.parse_expr()?; @@ -3099,6 +3105,16 @@ impl<'a> Parser<'a> { Ok(self.mk_expr(span_lo, hi, ExprKind::Loop(body, opt_ident), attrs)) } + /// Parse a `do catch {...}` expression (`do catch` token already eaten) + pub fn parse_catch_expr(&mut self, span_lo: BytePos, mut attrs: ThinVec<Attribute>) + -> PResult<'a, P<Expr>> + { + let (iattrs, body) = self.parse_inner_attrs_and_block()?; + attrs.extend(iattrs); + let hi = body.span.hi; + Ok(self.mk_expr(span_lo, hi, ExprKind::Catch(body), attrs)) + } + // `match` token already eaten fn parse_match_expr(&mut self, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> { let match_span = self.prev_span; @@ -3706,6 +3722,15 @@ impl<'a> Parser<'a> { }) } + fn is_catch_expr(&mut self) -> bool { + self.token.is_keyword(keywords::Do) && + self.look_ahead(1, |t| t.is_keyword(keywords::Catch)) && + self.look_ahead(2, |t| *t == token::OpenDelim(token::Brace)) && + + // prevent `while catch {} {}`, `if catch {} {} else {}`, etc. + !self.restrictions.contains(Restrictions::RESTRICTION_NO_STRUCT_LITERAL) + } + fn is_union_item(&self) -> bool { self.token.is_keyword(keywords::Union) && self.look_ahead(1, |t| t.is_ident() && !t.is_any_keyword()) @@ -4882,6 +4907,7 @@ impl<'a> Parser<'a> { /// Parse struct Foo { ... } fn parse_item_struct(&mut self) -> PResult<'a, ItemInfo> { let class_name = self.parse_ident()?; + let mut generics = self.parse_generics()?; // There is a special case worth noting here, as reported in issue #17904. @@ -4931,6 +4957,7 @@ impl<'a> Parser<'a> { /// Parse union Foo { ... } fn parse_item_union(&mut self) -> PResult<'a, ItemInfo> { let class_name = self.parse_ident()?; + let mut generics = self.parse_generics()?; let vdata = if self.token.is_keyword(keywords::Where) { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 5b65aac92b8..25601f2420e 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -86,6 +86,7 @@ fn ident_can_begin_expr(ident: ast::Ident) -> bool { !ident_token.is_any_keyword() || ident_token.is_path_segment_keyword() || [ + keywords::Do.name(), keywords::Box.name(), keywords::Break.name(), keywords::Continue.name(), |
