about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-08-23 11:46:24 +0000
committerbors <bors@rust-lang.org>2018-08-23 11:46:24 +0000
commit35bf1ae25799a4e62131159f052e0a3cbd27c960 (patch)
tree5f02fe2f099363dc95e480b4f9a62d6c79eaaafb /src/libsyntax
parent827e57c2f69a9caad36fab189770ad0bb8957d4f (diff)
parent009547141729b6d66f721065820edf9ddbde4831 (diff)
downloadrust-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...

~~Fix​es 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.rs6
-rw-r--r--src/libsyntax/feature_gate.rs8
-rw-r--r--src/libsyntax/fold.rs2
-rw-r--r--src/libsyntax/lib.rs2
-rw-r--r--src/libsyntax/parse/classify.rs2
-rw-r--r--src/libsyntax/parse/parser.rs40
-rw-r--r--src/libsyntax/print/pprust.rs4
-rw-r--r--src/libsyntax/util/parser.rs4
-rw-r--r--src/libsyntax/visit.rs2
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)
         }
     }