diff options
| author | bors <bors@rust-lang.org> | 2018-08-23 11:46:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-08-23 11:46:24 +0000 |
| commit | 35bf1ae25799a4e62131159f052e0a3cbd27c960 (patch) | |
| tree | 5f02fe2f099363dc95e480b4f9a62d6c79eaaafb /src/libsyntax | |
| parent | 827e57c2f69a9caad36fab189770ad0bb8957d4f (diff) | |
| parent | 009547141729b6d66f721065820edf9ddbde4831 (diff) | |
| download | rust-35bf1ae25799a4e62131159f052e0a3cbd27c960.tar.gz rust-35bf1ae25799a4e62131159f052e0a3cbd27c960.zip | |
Auto merge of #52602 - scottmcm:tryblock-expr, r=nikomatsakis
Implement try block expressions I noticed that `try` wasn't a keyword yet in Rust 2018, so... ~~Fixes https://github.com/rust-lang/rust/issues/52604~~ That was fixed by PR https://github.com/rust-lang/rust/pull/53135 cc https://github.com/rust-lang/rust/issues/31436 https://github.com/rust-lang/rust/issues/50412
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/lib.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/classify.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 40 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/util/parser.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 2 |
9 files changed, 45 insertions, 25 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index ec6ac86ba6b..b6084bcf343 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -987,7 +987,7 @@ impl Expr { ExprKind::Match(..) => ExprPrecedence::Match, ExprKind::Closure(..) => ExprPrecedence::Closure, ExprKind::Block(..) => ExprPrecedence::Block, - ExprKind::Catch(..) => ExprPrecedence::Catch, + ExprKind::TryBlock(..) => ExprPrecedence::TryBlock, ExprKind::Async(..) => ExprPrecedence::Async, ExprKind::Assign(..) => ExprPrecedence::Assign, ExprKind::AssignOp(..) => ExprPrecedence::AssignOp, @@ -1108,8 +1108,8 @@ pub enum ExprKind { /// created during lowering cannot be made the parent of any other /// preexisting defs. Async(CaptureBy, NodeId, P<Block>), - /// A catch block (`catch { ... }`) - Catch(P<Block>), + /// A try block (`try { ... }`) + TryBlock(P<Block>), /// An assignment (`a = foo()`) Assign(P<Expr>, P<Expr>), diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 8b5757e382e..1ffb6e55f06 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -333,8 +333,8 @@ declare_features! ( // `extern "x86-interrupt" fn()` (active, abi_x86_interrupt, "1.17.0", Some(40180), None), - // Allows the `catch {...}` expression - (active, catch_expr, "1.17.0", Some(31436), None), + // Allows the `try {...}` expression + (active, try_blocks, "1.29.0", Some(31436), None), // Used to preserve symbols (see llvm.used) (active, used, "1.18.0", Some(40289), None), @@ -1734,8 +1734,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { e.span, "yield syntax is experimental"); } - ast::ExprKind::Catch(_) => { - gate_feature_post!(&self, catch_expr, e.span, "`catch` expression is experimental"); + ast::ExprKind::TryBlock(_) => { + gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental"); } ast::ExprKind::IfLet(ref pats, ..) | ast::ExprKind::WhileLet(ref pats, ..) => { if pats.len() > 1 { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 50a49e2f548..050d21674f9 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1351,7 +1351,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu } ExprKind::Yield(ex) => ExprKind::Yield(ex.map(|x| folder.fold_expr(x))), ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)), - ExprKind::Catch(body) => ExprKind::Catch(folder.fold_block(body)), + ExprKind::TryBlock(body) => ExprKind::TryBlock(folder.fold_block(body)), }, id: folder.new_id(id), span: folder.new_span(span), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 289f023cefa..366b91fc828 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -26,8 +26,8 @@ #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] #![feature(str_escape)] +#![feature(try_trait)] #![feature(unicode_internals)] -#![feature(catch_expr)] #![recursion_limit="256"] diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 531483e7de1..99f9d0511fe 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -31,7 +31,7 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { ast::ExprKind::WhileLet(..) | ast::ExprKind::Loop(..) | ast::ExprKind::ForLoop(..) | - ast::ExprKind::Catch(..) => false, + ast::ExprKind::TryBlock(..) => false, _ => true, } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e85b5dca2b7..1e72f834b8e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1757,9 +1757,17 @@ impl<'a> Parser<'a> { let parser_snapshot_before_pat = self.clone(); + // Once we can use edition 2018 in the compiler, + // replace this with real try blocks. + macro_rules! try_block { + ($($inside:tt)*) => ( + (||{ ::std::ops::Try::from_ok({ $($inside)* }) })() + ) + } + // We're going to try parsing the argument as a pattern (even though it's not // allowed). This way we can provide better errors to the user. - let pat_arg: PResult<'a, _> = do catch { + let pat_arg: PResult<'a, _> = try_block! { let pat = self.parse_pat()?; self.expect(&token::Colon)?; (pat, self.parse_ty()?) @@ -2387,11 +2395,15 @@ impl<'a> Parser<'a> { BlockCheckMode::Unsafe(ast::UserProvided), attrs); } - if self.is_catch_expr() { + if self.is_do_catch_block() { + let mut db = self.fatal("found removed `do catch` syntax"); + db.help("Following RFC #2388, the new non-placeholder syntax is `try`"); + return Err(db); + } + if self.is_try_block() { let lo = self.span; - assert!(self.eat_keyword(keywords::Do)); - assert!(self.eat_keyword(keywords::Catch)); - return self.parse_catch_expr(lo, attrs); + assert!(self.eat_keyword(keywords::Try)); + return self.parse_try_block(lo, attrs); } if self.eat_keyword(keywords::Return) { if self.token.can_begin_expr() { @@ -3453,13 +3465,13 @@ impl<'a> Parser<'a> { ExprKind::Async(capture_clause, ast::DUMMY_NODE_ID, body), attrs)) } - /// Parse a `do catch {...}` expression (`do catch` token already eaten) - fn parse_catch_expr(&mut self, span_lo: Span, mut attrs: ThinVec<Attribute>) + /// Parse a `try {...}` expression (`try` token already eaten) + fn parse_try_block(&mut self, span_lo: Span, mut attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> { let (iattrs, body) = self.parse_inner_attrs_and_block()?; attrs.extend(iattrs); - Ok(self.mk_expr(span_lo.to(body.span), ExprKind::Catch(body), attrs)) + Ok(self.mk_expr(span_lo.to(body.span), ExprKind::TryBlock(body), attrs)) } // `match` token already eaten @@ -4408,12 +4420,20 @@ impl<'a> Parser<'a> { ) } - fn is_catch_expr(&mut self) -> bool { + fn is_do_catch_block(&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)) && + !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) + } + + fn is_try_block(&mut self) -> bool { + self.token.is_keyword(keywords::Try) && + self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) && + + self.span.edition() >= Edition::Edition2018 && - // prevent `while catch {} {}`, `if catch {} {} else {}`, etc. + // prevent `while try {} {}`, `if try {} {} else {}`, etc. !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL) } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3065e795ed8..be63c8f060a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2379,8 +2379,8 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(e, parser::PREC_POSTFIX)?; self.s.word("?")? } - ast::ExprKind::Catch(ref blk) => { - self.head("do catch")?; + ast::ExprKind::TryBlock(ref blk) => { + self.head("try")?; self.s.space()?; self.print_block_with_attrs(blk, attrs)? } diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index 67bc6f947b5..6866806cd7c 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -273,7 +273,7 @@ pub enum ExprPrecedence { Loop, Match, Block, - Catch, + TryBlock, Struct, Async, } @@ -332,7 +332,7 @@ impl ExprPrecedence { ExprPrecedence::Loop | ExprPrecedence::Match | ExprPrecedence::Block | - ExprPrecedence::Catch | + ExprPrecedence::TryBlock | ExprPrecedence::Async | ExprPrecedence::Struct => PREC_PAREN, } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 51be129737e..e57d692faae 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -809,7 +809,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { ExprKind::Try(ref subexpression) => { visitor.visit_expr(subexpression) } - ExprKind::Catch(ref body) => { + ExprKind::TryBlock(ref body) => { visitor.visit_block(body) } } |
