From f2445fb5075fa35d9b387d40bf6053007e63361e Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 21 Jul 2018 18:47:02 -0700 Subject: Rename `Catch` variants to `TryBlock` (Not `Try` since `QuestionMark` is using that.) --- src/libsyntax/ast.rs | 6 +++--- src/libsyntax/feature_gate.rs | 2 +- src/libsyntax/fold.rs | 2 +- src/libsyntax/parse/classify.rs | 2 +- src/libsyntax/parse/parser.rs | 2 +- src/libsyntax/print/pprust.rs | 2 +- src/libsyntax/util/parser.rs | 4 ++-- src/libsyntax/visit.rs | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index e53f3ea9036..0f2afde8f9e 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), - /// A catch block (`catch { ... }`) - Catch(P), + /// A try block (`try { ... }`) + TryBlock(P), /// An assignment (`a = foo()`) Assign(P, P), diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index e8245a553eb..32769130940 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1734,7 +1734,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { e.span, "yield syntax is experimental"); } - ast::ExprKind::Catch(_) => { + ast::ExprKind::TryBlock(_) => { gate_feature_post!(&self, catch_expr, e.span, "`catch` expression is experimental"); } ast::ExprKind::IfLet(ref pats, ..) | ast::ExprKind::WhileLet(ref pats, ..) => { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 3209939d9b1..632dd5c3309 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1351,7 +1351,7 @@ pub fn noop_fold_expr(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/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 345464c6664..fdb9f80b7c6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -3458,7 +3458,7 @@ impl<'a> Parser<'a> { { 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 diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 54ce06f61ef..f8d01fee950 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2379,7 +2379,7 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(e, parser::PREC_POSTFIX)?; self.s.word("?")? } - ast::ExprKind::Catch(ref blk) => { + ast::ExprKind::TryBlock(ref blk) => { self.head("do catch")?; 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) } } -- cgit 1.4.1-3-g733a5 From 9e64ce179903e610197e1d201a53471e9feb69f2 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 21 Jul 2018 20:59:44 -0700 Subject: Parse try blocks with the try keyword instead of do catch placeholder --- src/librustc_mir/borrow_check/nll/mod.rs | 4 +- src/librustc_mir/lib.rs | 9 ++- src/librustc_mir/util/pretty.rs | 4 +- src/librustc_typeck/check/mod.rs | 2 +- src/libsyntax/feature_gate.rs | 4 +- src/libsyntax/parse/parser.rs | 22 +++--- src/libsyntax/print/pprust.rs | 2 +- src/libsyntax_pos/hygiene.rs | 2 +- src/test/compile-fail/try-block-bad-lifetime.rs | 44 ++++++++++++ src/test/compile-fail/try-block-bad-type.rs | 30 ++++++++ src/test/compile-fail/try-block-in-match.rs | 17 +++++ src/test/compile-fail/try-block-in-while.rs | 17 +++++ .../compile-fail/try-block-maybe-bad-lifetime.rs | 51 ++++++++++++++ src/test/compile-fail/try-block-opt-init.rs | 27 ++++++++ src/test/run-pass/catch-expr.rs | 79 --------------------- src/test/run-pass/issue-45124.rs | 4 +- src/test/run-pass/try-block.rs | 81 ++++++++++++++++++++++ src/test/ui/catch/catch-bad-lifetime.nll.stderr | 39 ----------- src/test/ui/catch/catch-bad-lifetime.rs | 42 ----------- src/test/ui/catch/catch-bad-lifetime.stderr | 44 ------------ src/test/ui/catch/catch-bad-type.rs | 28 -------- src/test/ui/catch/catch-bad-type.stderr | 52 -------------- src/test/ui/catch/catch-block-type-error.rs | 26 ------- src/test/ui/catch/catch-block-type-error.stderr | 24 ------- src/test/ui/catch/catch-in-match.rs | 15 ---- src/test/ui/catch/catch-in-match.stderr | 8 --- src/test/ui/catch/catch-in-while.rs | 15 ---- src/test/ui/catch/catch-in-while.stderr | 8 --- .../ui/catch/catch-maybe-bad-lifetime.nll.stderr | 14 ---- src/test/ui/catch/catch-maybe-bad-lifetime.rs | 49 ------------- src/test/ui/catch/catch-maybe-bad-lifetime.stderr | 33 --------- src/test/ui/catch/catch-opt-init.nll.stderr | 11 --- src/test/ui/catch/catch-opt-init.rs | 25 ------- src/test/ui/catch/catch-opt-init.stderr | 9 --- .../ui/feature-gates/feature-gate-catch_expr.rs | 6 +- .../feature-gates/feature-gate-catch_expr.stderr | 8 +-- src/test/ui/try-block-in-edition2015.rs | 20 ++++++ src/test/ui/try-block-in-edition2015.stderr | 18 +++++ src/test/ui/try-block-type-error.rs | 28 ++++++++ src/test/ui/try-block-type-error.stderr | 24 +++++++ 40 files changed, 396 insertions(+), 549 deletions(-) create mode 100644 src/test/compile-fail/try-block-bad-lifetime.rs create mode 100644 src/test/compile-fail/try-block-bad-type.rs create mode 100644 src/test/compile-fail/try-block-in-match.rs create mode 100644 src/test/compile-fail/try-block-in-while.rs create mode 100644 src/test/compile-fail/try-block-maybe-bad-lifetime.rs create mode 100644 src/test/compile-fail/try-block-opt-init.rs delete mode 100644 src/test/run-pass/catch-expr.rs create mode 100644 src/test/run-pass/try-block.rs delete mode 100644 src/test/ui/catch/catch-bad-lifetime.nll.stderr delete mode 100644 src/test/ui/catch/catch-bad-lifetime.rs delete mode 100644 src/test/ui/catch/catch-bad-lifetime.stderr delete mode 100644 src/test/ui/catch/catch-bad-type.rs delete mode 100644 src/test/ui/catch/catch-bad-type.stderr delete mode 100644 src/test/ui/catch/catch-block-type-error.rs delete mode 100644 src/test/ui/catch/catch-block-type-error.stderr delete mode 100644 src/test/ui/catch/catch-in-match.rs delete mode 100644 src/test/ui/catch/catch-in-match.stderr delete mode 100644 src/test/ui/catch/catch-in-while.rs delete mode 100644 src/test/ui/catch/catch-in-while.stderr delete mode 100644 src/test/ui/catch/catch-maybe-bad-lifetime.nll.stderr delete mode 100644 src/test/ui/catch/catch-maybe-bad-lifetime.rs delete mode 100644 src/test/ui/catch/catch-maybe-bad-lifetime.stderr delete mode 100644 src/test/ui/catch/catch-opt-init.nll.stderr delete mode 100644 src/test/ui/catch/catch-opt-init.rs delete mode 100644 src/test/ui/catch/catch-opt-init.stderr create mode 100644 src/test/ui/try-block-in-edition2015.rs create mode 100644 src/test/ui/try-block-in-edition2015.stderr create mode 100644 src/test/ui/try-block-type-error.rs create mode 100644 src/test/ui/try-block-type-error.stderr (limited to 'src/libsyntax') diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index f54d80d5f4f..40df78d6bfd 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -312,14 +312,14 @@ fn dump_mir_results<'a, 'gcx, 'tcx>( ); // Also dump the inference graph constraints as a graphviz file. - let _: io::Result<()> = do catch { + let _: io::Result<()> = try_block! { let mut file = pretty::create_dump_file(infcx.tcx, "regioncx.all.dot", None, "nll", &0, source)?; regioncx.dump_graphviz_raw_constraints(&mut file)?; }; // Also dump the inference graph constraints as a graphviz file. - let _: io::Result<()> = do catch { + let _: io::Result<()> = try_block! { let mut file = pretty::create_dump_file(infcx.tcx, "regioncx.scc.dot", None, "nll", &0, source)?; regioncx.dump_graphviz_scc_constraints(&mut file)?; diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index bda80ff562c..3858aae3d5c 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -21,7 +21,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(slice_sort_by_cached_key)] #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(catch_expr)] #![feature(crate_visibility_modifier)] #![feature(const_fn)] #![feature(core_intrinsics)] @@ -61,6 +60,14 @@ extern crate rustc_apfloat; extern crate byteorder; extern crate core; +// 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)* }) })() + ) +} + mod diagnostics; mod borrow_check; diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index 01ad85cf668..465dad35ae3 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -140,7 +140,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( ) where F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>, { - let _: io::Result<()> = do catch { + let _: io::Result<()> = try_block! { let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?; writeln!(file, "// MIR for `{}`", node_path)?; writeln!(file, "// source = {:?}", source)?; @@ -156,7 +156,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>( }; if tcx.sess.opts.debugging_opts.dump_mir_graphviz { - let _: io::Result<()> = do catch { + let _: io::Result<()> = try_block! { let mut file = create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?; write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?; diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 27b427f7f89..89537634ad9 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4461,7 +4461,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // In some cases, blocks have just one exit, but other blocks // can be targeted by multiple breaks. This can happen both // with labeled blocks as well as when we desugar - // a `do catch { ... }` expression. + // a `try { ... }` expression. // // Example 1: // diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 32769130940..f796c0e2e53 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -330,7 +330,7 @@ declare_features! ( // `extern "x86-interrupt" fn()` (active, abi_x86_interrupt, "1.17.0", Some(40180), None), - // Allows the `catch {...}` expression + // Allows the `try {...}` expression (active, catch_expr, "1.17.0", Some(31436), None), // Used to preserve symbols (see llvm.used) @@ -1735,7 +1735,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { "yield syntax is experimental"); } ast::ExprKind::TryBlock(_) => { - gate_feature_post!(&self, catch_expr, e.span, "`catch` expression is experimental"); + gate_feature_post!(&self, catch_expr, 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/parse/parser.rs b/src/libsyntax/parse/parser.rs index fdb9f80b7c6..2b0cfd14a3d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2386,11 +2386,10 @@ impl<'a> Parser<'a> { BlockCheckMode::Unsafe(ast::UserProvided), attrs); } - if self.is_catch_expr() { + 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() { @@ -3452,8 +3451,8 @@ 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) + /// Parse a `try {...}` expression (`try` token already eaten) + fn parse_try_block(&mut self, span_lo: Span, mut attrs: ThinVec) -> PResult<'a, P> { let (iattrs, body) = self.parse_inner_attrs_and_block()?; @@ -4407,12 +4406,13 @@ 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)) && + fn is_try_block(&mut self) -> bool { + self.token.is_keyword(keywords::Try) && + self.look_ahead(1, |t| *t == token::OpenDelim(token::Brace)) && - // prevent `while catch {} {}`, `if catch {} {} else {}`, etc. + self.span.edition() >= Edition::Edition2018 && + + // 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 f8d01fee950..14e7b08172b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2380,7 +2380,7 @@ impl<'a> State<'a> { self.s.word("?")? } ast::ExprKind::TryBlock(ref blk) => { - self.head("do catch")?; + self.head("try")?; self.s.space()?; self.print_block_with_attrs(blk, attrs)? } diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 56901917450..364c640debb 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -609,7 +609,7 @@ impl CompilerDesugaringKind { Symbol::intern(match self { CompilerDesugaringKind::Async => "async", CompilerDesugaringKind::QuestionMark => "?", - CompilerDesugaringKind::TryBlock => "do catch", + CompilerDesugaringKind::TryBlock => "try block", CompilerDesugaringKind::ExistentialReturnType => "existential type", CompilerDesugaringKind::ForLoop => "for loop", }) diff --git a/src/test/compile-fail/try-block-bad-lifetime.rs b/src/test/compile-fail/try-block-bad-lifetime.rs new file mode 100644 index 00000000000..8dfd8545af7 --- /dev/null +++ b/src/test/compile-fail/try-block-bad-lifetime.rs @@ -0,0 +1,44 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +#![feature(catch_expr)] + +// This test checks that borrows made and returned inside try blocks are properly constrained +pub fn main() { + { + // Test that borrows returned from a try block must be valid for the lifetime of the + // result variable + let _result: Result<(), &str> = try { + let my_string = String::from(""); + let my_str: & str = & my_string; + //~^ ERROR `my_string` does not live long enough + Err(my_str) ?; + Err("") ?; + }; + } + + { + // Test that borrows returned from try blocks freeze their referent + let mut i = 5; + let k = &mut i; + let mut j: Result<(), &mut i32> = try { + Err(k) ?; + i = 10; //~ ERROR cannot assign to `i` because it is borrowed + }; + ::std::mem::drop(k); //~ ERROR use of moved value: `k` + i = 40; //~ ERROR cannot assign to `i` because it is borrowed + + let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic ! ("") }; + *i_ptr = 50; + } +} + diff --git a/src/test/compile-fail/try-block-bad-type.rs b/src/test/compile-fail/try-block-bad-type.rs new file mode 100644 index 00000000000..9e555df8535 --- /dev/null +++ b/src/test/compile-fail/try-block-bad-type.rs @@ -0,0 +1,30 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +#![feature(catch_expr)] + +pub fn main() { + let res: Result = try { + Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>` is not satisfied + 5 + }; + + let res: Result = try { + "" //~ ERROR type mismatch + }; + + let res: Result = try { }; //~ ERROR type mismatch + + let res: () = try { }; //~ the trait bound `(): std::ops::Try` is not satisfied + + let res: i32 = try { 5 }; //~ ERROR the trait bound `i32: std::ops::Try` is not satisfied +} diff --git a/src/test/compile-fail/try-block-in-match.rs b/src/test/compile-fail/try-block-in-match.rs new file mode 100644 index 00000000000..490b00a6f43 --- /dev/null +++ b/src/test/compile-fail/try-block-in-match.rs @@ -0,0 +1,17 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +#![feature(catch_expr)] + +fn main() { + match try { false } { _ => {} } //~ ERROR expected expression, found keyword `try` +} diff --git a/src/test/compile-fail/try-block-in-while.rs b/src/test/compile-fail/try-block-in-while.rs new file mode 100644 index 00000000000..a949e778f38 --- /dev/null +++ b/src/test/compile-fail/try-block-in-while.rs @@ -0,0 +1,17 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +#![feature(catch_expr)] + +fn main() { + while try { false } {} //~ ERROR expected expression, found keyword `try` +} diff --git a/src/test/compile-fail/try-block-maybe-bad-lifetime.rs b/src/test/compile-fail/try-block-maybe-bad-lifetime.rs new file mode 100644 index 00000000000..db37a397c16 --- /dev/null +++ b/src/test/compile-fail/try-block-maybe-bad-lifetime.rs @@ -0,0 +1,51 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +#![feature(catch_expr)] + +// This test checks that borrows made and returned inside try blocks are properly constrained +pub fn main() { + { + // Test that a borrow which *might* be returned still freezes its referent + let mut i = 222; + let x: Result<&i32, ()> = try { + Err(())?; + &i + }; + x.ok().cloned(); + i = 0; //~ ERROR cannot assign to `i` because it is borrowed + let _ = i; + } + + { + let x = String::new(); + let _y: Result<(), ()> = try { + Err(())?; + ::std::mem::drop(x); + }; + println!("{}", x); //~ ERROR use of moved value: `x` + } + + { + // Test that a borrow which *might* be assigned to an outer variable still freezes + // its referent + let mut i = 222; + let j; + let x: Result<(), ()> = try { + Err(())?; + j = &i; + }; + i = 0; //~ ERROR cannot assign to `i` because it is borrowed + let _ = i; + } +} + diff --git a/src/test/compile-fail/try-block-opt-init.rs b/src/test/compile-fail/try-block-opt-init.rs new file mode 100644 index 00000000000..14544c6ea0c --- /dev/null +++ b/src/test/compile-fail/try-block-opt-init.rs @@ -0,0 +1,27 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +#![feature(catch_expr)] + +fn use_val(_x: T) {} + +pub fn main() { + let cfg_res; + let _: Result<(), ()> = try { + Err(())?; + cfg_res = 5; + Ok::<(), ()>(())?; + use_val(cfg_res); + }; + assert_eq!(cfg_res, 5); //~ ERROR use of possibly uninitialized variable +} + diff --git a/src/test/run-pass/catch-expr.rs b/src/test/run-pass/catch-expr.rs deleted file mode 100644 index c23bca7f49e..00000000000 --- a/src/test/run-pass/catch-expr.rs +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(catch_expr)] - -struct catch {} - -pub fn main() { - let catch_result: Option<_> = do catch { - let x = 5; - x - }; - assert_eq!(catch_result, Some(5)); - - let mut catch = true; - while catch { catch = false; } - assert_eq!(catch, false); - - catch = if catch { false } else { true }; - assert_eq!(catch, true); - - match catch { - _ => {} - }; - - let catch_err: Result<_, i32> = do catch { - Err(22)?; - 1 - }; - assert_eq!(catch_err, Err(22)); - - let catch_okay: Result = do catch { - if false { Err(25)?; } - Ok::<(), i32>(())?; - 28 - }; - assert_eq!(catch_okay, Ok(28)); - - let catch_from_loop: Result = do catch { - for i in 0..10 { - if i < 5 { Ok::(i)?; } else { Err(i)?; } - } - 22 - }; - assert_eq!(catch_from_loop, Err(5)); - - let cfg_init; - let _res: Result<(), ()> = do catch { - cfg_init = 5; - }; - assert_eq!(cfg_init, 5); - - let cfg_init_2; - let _res: Result<(), ()> = do catch { - cfg_init_2 = 6; - Err(())?; - }; - assert_eq!(cfg_init_2, 6); - - let my_string = "test".to_string(); - let res: Result<&str, ()> = do catch { - // Unfortunately, deref doesn't fire here (#49356) - &my_string[..] - }; - assert_eq!(res, Ok("test")); - - let my_opt: Option<_> = do catch { () }; - assert_eq!(my_opt, Some(())); - - let my_opt: Option<_> = do catch { }; - assert_eq!(my_opt, Some(())); -} diff --git a/src/test/run-pass/issue-45124.rs b/src/test/run-pass/issue-45124.rs index c65823e460b..5f47cc8d7d5 100644 --- a/src/test/run-pass/issue-45124.rs +++ b/src/test/run-pass/issue-45124.rs @@ -8,12 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: --edition 2018 + #![feature(catch_expr)] fn main() { let mut a = 0; let () = { - let _: Result<(), ()> = do catch { + let _: Result<(), ()> = try { let _ = Err(())?; return }; diff --git a/src/test/run-pass/try-block.rs b/src/test/run-pass/try-block.rs new file mode 100644 index 00000000000..f2b017e94f0 --- /dev/null +++ b/src/test/run-pass/try-block.rs @@ -0,0 +1,81 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +#![feature(catch_expr)] + +struct catch {} + +pub fn main() { + let catch_result: Option<_> = try { + let x = 5; + x + }; + assert_eq!(catch_result, Some(5)); + + let mut catch = true; + while catch { catch = false; } + assert_eq!(catch, false); + + catch = if catch { false } else { true }; + assert_eq!(catch, true); + + match catch { + _ => {} + }; + + let catch_err: Result<_, i32> = try { + Err(22)?; + 1 + }; + assert_eq!(catch_err, Err(22)); + + let catch_okay: Result = try { + if false { Err(25)?; } + Ok::<(), i32>(())?; + 28 + }; + assert_eq!(catch_okay, Ok(28)); + + let catch_from_loop: Result = try { + for i in 0..10 { + if i < 5 { Ok::(i)?; } else { Err(i)?; } + } + 22 + }; + assert_eq!(catch_from_loop, Err(5)); + + let cfg_init; + let _res: Result<(), ()> = try { + cfg_init = 5; + }; + assert_eq!(cfg_init, 5); + + let cfg_init_2; + let _res: Result<(), ()> = try { + cfg_init_2 = 6; + Err(())?; + }; + assert_eq!(cfg_init_2, 6); + + let my_string = "test".to_string(); + let res: Result<&str, ()> = try { + // Unfortunately, deref doesn't fire here (#49356) + &my_string[..] + }; + assert_eq!(res, Ok("test")); + + let my_opt: Option<_> = try { () }; + assert_eq!(my_opt, Some(())); + + let my_opt: Option<_> = try { }; + assert_eq!(my_opt, Some(())); +} diff --git a/src/test/ui/catch/catch-bad-lifetime.nll.stderr b/src/test/ui/catch/catch-bad-lifetime.nll.stderr deleted file mode 100644 index dd1595f9315..00000000000 --- a/src/test/ui/catch/catch-bad-lifetime.nll.stderr +++ /dev/null @@ -1,39 +0,0 @@ -error[E0506]: cannot assign to `i` because it is borrowed - --> $DIR/catch-bad-lifetime.rs:33:13 - | -LL | let k = &mut i; - | ------ borrow of `i` occurs here -... -LL | i = 10; //~ ERROR cannot assign to `i` because it is borrowed - | ^^^^^^ assignment to borrowed `i` occurs here -LL | }; -LL | ::std::mem::drop(k); //~ ERROR use of moved value: `k` - | - borrow later used here - -error[E0382]: use of moved value: `k` - --> $DIR/catch-bad-lifetime.rs:35:26 - | -LL | Err(k) ?; - | - value moved here -... -LL | ::std::mem::drop(k); //~ ERROR use of moved value: `k` - | ^ value used here after move - | - = note: move occurs because `k` has type `&mut i32`, which does not implement the `Copy` trait - -error[E0506]: cannot assign to `i` because it is borrowed - --> $DIR/catch-bad-lifetime.rs:36:9 - | -LL | let k = &mut i; - | ------ borrow of `i` occurs here -... -LL | i = 40; //~ ERROR cannot assign to `i` because it is borrowed - | ^^^^^^ assignment to borrowed `i` occurs here -LL | -LL | let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic ! ("") }; - | - borrow later used here - -error: aborting due to 3 previous errors - -Some errors occurred: E0382, E0506. -For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/catch/catch-bad-lifetime.rs b/src/test/ui/catch/catch-bad-lifetime.rs deleted file mode 100644 index f332ffd4494..00000000000 --- a/src/test/ui/catch/catch-bad-lifetime.rs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(catch_expr)] - -// This test checks that borrows made and returned inside catch blocks are properly constrained -pub fn main() { - { - // Test that borrows returned from a catch block must be valid for the lifetime of the - // result variable - let _result: Result<(), &str> = do catch { - let my_string = String::from(""); - let my_str: & str = & my_string; - //~^ ERROR `my_string` does not live long enough - Err(my_str) ?; - Err("") ?; - }; - } - - { - // Test that borrows returned from catch blocks freeze their referent - let mut i = 5; - let k = &mut i; - let mut j: Result<(), &mut i32> = do catch { - Err(k) ?; - i = 10; //~ ERROR cannot assign to `i` because it is borrowed - }; - ::std::mem::drop(k); //~ ERROR use of moved value: `k` - i = 40; //~ ERROR cannot assign to `i` because it is borrowed - - let i_ptr = if let Err(i_ptr) = j { i_ptr } else { panic ! ("") }; - *i_ptr = 50; - } -} - diff --git a/src/test/ui/catch/catch-bad-lifetime.stderr b/src/test/ui/catch/catch-bad-lifetime.stderr deleted file mode 100644 index 2ea54d1fb24..00000000000 --- a/src/test/ui/catch/catch-bad-lifetime.stderr +++ /dev/null @@ -1,44 +0,0 @@ -error[E0597]: `my_string` does not live long enough - --> $DIR/catch-bad-lifetime.rs:20:35 - | -LL | let my_str: & str = & my_string; - | ^^^^^^^^^ borrowed value does not live long enough -... -LL | }; - | - `my_string` dropped here while still borrowed -LL | } - | - borrowed value needs to live until here - -error[E0506]: cannot assign to `i` because it is borrowed - --> $DIR/catch-bad-lifetime.rs:33:13 - | -LL | let k = &mut i; - | - borrow of `i` occurs here -... -LL | i = 10; //~ ERROR cannot assign to `i` because it is borrowed - | ^^^^^^ assignment to borrowed `i` occurs here - -error[E0382]: use of moved value: `k` - --> $DIR/catch-bad-lifetime.rs:35:26 - | -LL | Err(k) ?; - | - value moved here -... -LL | ::std::mem::drop(k); //~ ERROR use of moved value: `k` - | ^ value used here after move - | - = note: move occurs because `k` has type `&mut i32`, which does not implement the `Copy` trait - -error[E0506]: cannot assign to `i` because it is borrowed - --> $DIR/catch-bad-lifetime.rs:36:9 - | -LL | let k = &mut i; - | - borrow of `i` occurs here -... -LL | i = 40; //~ ERROR cannot assign to `i` because it is borrowed - | ^^^^^^ assignment to borrowed `i` occurs here - -error: aborting due to 4 previous errors - -Some errors occurred: E0382, E0506, E0597. -For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/catch/catch-bad-type.rs b/src/test/ui/catch/catch-bad-type.rs deleted file mode 100644 index b369847699b..00000000000 --- a/src/test/ui/catch/catch-bad-type.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(catch_expr)] - -pub fn main() { - let res: Result = do catch { - Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>` is not satisfied - 5 - }; - - let res: Result = do catch { - "" //~ ERROR type mismatch - }; - - let res: Result = do catch { }; //~ ERROR type mismatch - - let res: () = do catch { }; //~ the trait bound `(): std::ops::Try` is not satisfied - - let res: i32 = do catch { 5 }; //~ ERROR the trait bound `i32: std::ops::Try` is not satisfied -} diff --git a/src/test/ui/catch/catch-bad-type.stderr b/src/test/ui/catch/catch-bad-type.stderr deleted file mode 100644 index 2ab5b3e3176..00000000000 --- a/src/test/ui/catch/catch-bad-type.stderr +++ /dev/null @@ -1,52 +0,0 @@ -error[E0277]: the trait bound `i32: std::convert::From<&str>` is not satisfied - --> $DIR/catch-bad-type.rs:15:9 - | -LL | Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>` is not satisfied - | ^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `i32` - | - = help: the following implementations were found: - > - > - > - > - > - = note: required by `std::convert::From::from` - -error[E0271]: type mismatch resolving ` as std::ops::Try>::Ok == &str` - --> $DIR/catch-bad-type.rs:20:9 - | -LL | "" //~ ERROR type mismatch - | ^^ expected i32, found &str - | - = note: expected type `i32` - found type `&str` - -error[E0271]: type mismatch resolving ` as std::ops::Try>::Ok == ()` - --> $DIR/catch-bad-type.rs:23:44 - | -LL | let res: Result = do catch { }; //~ ERROR type mismatch - | ^ expected i32, found () - | - = note: expected type `i32` - found type `()` - -error[E0277]: the trait bound `(): std::ops::Try` is not satisfied - --> $DIR/catch-bad-type.rs:25:28 - | -LL | let res: () = do catch { }; //~ the trait bound `(): std::ops::Try` is not satisfied - | ^^^ the trait `std::ops::Try` is not implemented for `()` - | - = note: required by `std::ops::Try::from_ok` - -error[E0277]: the trait bound `i32: std::ops::Try` is not satisfied - --> $DIR/catch-bad-type.rs:27:29 - | -LL | let res: i32 = do catch { 5 }; //~ ERROR the trait bound `i32: std::ops::Try` is not satisfied - | ^^^^^ the trait `std::ops::Try` is not implemented for `i32` - | - = note: required by `std::ops::Try::from_ok` - -error: aborting due to 5 previous errors - -Some errors occurred: E0271, E0277. -For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/catch/catch-block-type-error.rs b/src/test/ui/catch/catch-block-type-error.rs deleted file mode 100644 index 10130ef1e5d..00000000000 --- a/src/test/ui/catch/catch-block-type-error.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2018 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(catch_expr)] - -fn foo() -> Option<()> { Some(()) } - -fn main() { - let _: Option = do catch { - foo()?; - 42 - //~^ ERROR type mismatch - }; - - let _: Option = do catch { - foo()?; - }; - //~^ ERROR type mismatch -} diff --git a/src/test/ui/catch/catch-block-type-error.stderr b/src/test/ui/catch/catch-block-type-error.stderr deleted file mode 100644 index 288168c6992..00000000000 --- a/src/test/ui/catch/catch-block-type-error.stderr +++ /dev/null @@ -1,24 +0,0 @@ -error[E0271]: type mismatch resolving ` as std::ops::Try>::Ok == {integer}` - --> $DIR/catch-block-type-error.rs:18:9 - | -LL | 42 - | ^^ - | | - | expected f32, found integral variable - | help: use a float literal: `42.0` - | - = note: expected type `f32` - found type `{integer}` - -error[E0271]: type mismatch resolving ` as std::ops::Try>::Ok == ()` - --> $DIR/catch-block-type-error.rs:24:5 - | -LL | }; - | ^ expected i32, found () - | - = note: expected type `i32` - found type `()` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/catch/catch-in-match.rs b/src/test/ui/catch/catch-in-match.rs deleted file mode 100644 index 9f9968e8124..00000000000 --- a/src/test/ui/catch/catch-in-match.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(catch_expr)] - -fn main() { - match do catch { false } { _ => {} } //~ ERROR expected expression, found reserved keyword `do` -} diff --git a/src/test/ui/catch/catch-in-match.stderr b/src/test/ui/catch/catch-in-match.stderr deleted file mode 100644 index 1542989cc35..00000000000 --- a/src/test/ui/catch/catch-in-match.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected expression, found reserved keyword `do` - --> $DIR/catch-in-match.rs:14:11 - | -LL | match do catch { false } { _ => {} } //~ ERROR expected expression, found reserved keyword `do` - | ^^ expected expression - -error: aborting due to previous error - diff --git a/src/test/ui/catch/catch-in-while.rs b/src/test/ui/catch/catch-in-while.rs deleted file mode 100644 index cb8613ee60b..00000000000 --- a/src/test/ui/catch/catch-in-while.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(catch_expr)] - -fn main() { - while do catch { false } {} //~ ERROR expected expression, found reserved keyword `do` -} diff --git a/src/test/ui/catch/catch-in-while.stderr b/src/test/ui/catch/catch-in-while.stderr deleted file mode 100644 index 9316bbcd4bc..00000000000 --- a/src/test/ui/catch/catch-in-while.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: expected expression, found reserved keyword `do` - --> $DIR/catch-in-while.rs:14:11 - | -LL | while do catch { false } {} //~ ERROR expected expression, found reserved keyword `do` - | ^^ expected expression - -error: aborting due to previous error - diff --git a/src/test/ui/catch/catch-maybe-bad-lifetime.nll.stderr b/src/test/ui/catch/catch-maybe-bad-lifetime.nll.stderr deleted file mode 100644 index 157793160ce..00000000000 --- a/src/test/ui/catch/catch-maybe-bad-lifetime.nll.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error[E0382]: borrow of moved value: `x` - --> $DIR/catch-maybe-bad-lifetime.rs:33:24 - | -LL | ::std::mem::drop(x); - | - value moved here -LL | }; -LL | println!("{}", x); //~ ERROR use of moved value: `x` - | ^ value borrowed here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/catch/catch-maybe-bad-lifetime.rs b/src/test/ui/catch/catch-maybe-bad-lifetime.rs deleted file mode 100644 index faefb5ef18a..00000000000 --- a/src/test/ui/catch/catch-maybe-bad-lifetime.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(catch_expr)] - -// This test checks that borrows made and returned inside catch blocks are properly constrained -pub fn main() { - { - // Test that a borrow which *might* be returned still freezes its referent - let mut i = 222; - let x: Result<&i32, ()> = do catch { - Err(())?; - &i - }; - x.ok().cloned(); - i = 0; //~ ERROR cannot assign to `i` because it is borrowed - let _ = i; - } - - { - let x = String::new(); - let _y: Result<(), ()> = do catch { - Err(())?; - ::std::mem::drop(x); - }; - println!("{}", x); //~ ERROR use of moved value: `x` - } - - { - // Test that a borrow which *might* be assigned to an outer variable still freezes - // its referent - let mut i = 222; - let j; - let x: Result<(), ()> = do catch { - Err(())?; - j = &i; - }; - i = 0; //~ ERROR cannot assign to `i` because it is borrowed - let _ = i; - } -} - diff --git a/src/test/ui/catch/catch-maybe-bad-lifetime.stderr b/src/test/ui/catch/catch-maybe-bad-lifetime.stderr deleted file mode 100644 index 21fe1049f43..00000000000 --- a/src/test/ui/catch/catch-maybe-bad-lifetime.stderr +++ /dev/null @@ -1,33 +0,0 @@ -error[E0506]: cannot assign to `i` because it is borrowed - --> $DIR/catch-maybe-bad-lifetime.rs:23:9 - | -LL | &i - | - borrow of `i` occurs here -... -LL | i = 0; //~ ERROR cannot assign to `i` because it is borrowed - | ^^^^^ assignment to borrowed `i` occurs here - -error[E0382]: use of moved value: `x` - --> $DIR/catch-maybe-bad-lifetime.rs:33:24 - | -LL | ::std::mem::drop(x); - | - value moved here -LL | }; -LL | println!("{}", x); //~ ERROR use of moved value: `x` - | ^ value used here after move - | - = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait - -error[E0506]: cannot assign to `i` because it is borrowed - --> $DIR/catch-maybe-bad-lifetime.rs:45:9 - | -LL | j = &i; - | - borrow of `i` occurs here -LL | }; -LL | i = 0; //~ ERROR cannot assign to `i` because it is borrowed - | ^^^^^ assignment to borrowed `i` occurs here - -error: aborting due to 3 previous errors - -Some errors occurred: E0382, E0506. -For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/catch/catch-opt-init.nll.stderr b/src/test/ui/catch/catch-opt-init.nll.stderr deleted file mode 100644 index ea8c8ebdcb7..00000000000 --- a/src/test/ui/catch/catch-opt-init.nll.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0381]: borrow of possibly uninitialized variable: `cfg_res` - --> $DIR/catch-opt-init.rs:23:5 - | -LL | assert_eq!(cfg_res, 5); //~ ERROR use of possibly uninitialized variable - | ^^^^^^^^^^^^^^^^^^^^^^^ use of possibly uninitialized `cfg_res` - | - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/catch/catch-opt-init.rs b/src/test/ui/catch/catch-opt-init.rs deleted file mode 100644 index 0c41102e3be..00000000000 --- a/src/test/ui/catch/catch-opt-init.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(catch_expr)] - -fn use_val(_x: T) {} - -pub fn main() { - let cfg_res; - let _: Result<(), ()> = do catch { - Err(())?; - cfg_res = 5; - Ok::<(), ()>(())?; - use_val(cfg_res); - }; - assert_eq!(cfg_res, 5); //~ ERROR use of possibly uninitialized variable -} - diff --git a/src/test/ui/catch/catch-opt-init.stderr b/src/test/ui/catch/catch-opt-init.stderr deleted file mode 100644 index 6a14ba17f9e..00000000000 --- a/src/test/ui/catch/catch-opt-init.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0381]: use of possibly uninitialized variable: `cfg_res` - --> $DIR/catch-opt-init.rs:23:16 - | -LL | assert_eq!(cfg_res, 5); //~ ERROR use of possibly uninitialized variable - | ^^^^^^^ use of possibly uninitialized `cfg_res` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/feature-gates/feature-gate-catch_expr.rs b/src/test/ui/feature-gates/feature-gate-catch_expr.rs index 5568a5cf0aa..6536280c71f 100644 --- a/src/test/ui/feature-gates/feature-gate-catch_expr.rs +++ b/src/test/ui/feature-gates/feature-gate-catch_expr.rs @@ -8,10 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// compile-flags: --edition 2018 + pub fn main() { - let catch_result = do catch { //~ ERROR `catch` expression is experimental + let try_result: Option<_> = try { //~ ERROR `try` expression is experimental let x = 5; x }; - assert_eq!(catch_result, 5); + assert_eq!(try_result, Some(5)); } diff --git a/src/test/ui/feature-gates/feature-gate-catch_expr.stderr b/src/test/ui/feature-gates/feature-gate-catch_expr.stderr index 4ab71460c0d..4842215d51a 100644 --- a/src/test/ui/feature-gates/feature-gate-catch_expr.stderr +++ b/src/test/ui/feature-gates/feature-gate-catch_expr.stderr @@ -1,8 +1,8 @@ -error[E0658]: `catch` expression is experimental (see issue #31436) - --> $DIR/feature-gate-catch_expr.rs:12:24 +error[E0658]: `try` expression is experimental (see issue #31436) + --> $DIR/feature-gate-catch_expr.rs:14:33 | -LL | let catch_result = do catch { //~ ERROR `catch` expression is experimental - | ________________________^ +LL | let try_result: Option<_> = try { //~ ERROR `try` expression is experimental + | _________________________________^ LL | | let x = 5; LL | | x LL | | }; diff --git a/src/test/ui/try-block-in-edition2015.rs b/src/test/ui/try-block-in-edition2015.rs new file mode 100644 index 00000000000..64485bb8318 --- /dev/null +++ b/src/test/ui/try-block-in-edition2015.rs @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2015 + +pub fn main() { + let try_result: Option<_> = try { + //~^ ERROR expected struct, variant or union type, found macro `try` + let x = 5; //~ ERROR expected identifier, found keyword + x + }; + assert_eq!(try_result, Some(5)); +} diff --git a/src/test/ui/try-block-in-edition2015.stderr b/src/test/ui/try-block-in-edition2015.stderr new file mode 100644 index 00000000000..7e6d515e111 --- /dev/null +++ b/src/test/ui/try-block-in-edition2015.stderr @@ -0,0 +1,18 @@ +error: expected identifier, found keyword `let` + --> $DIR/try-block-in-edition2015.rs:16:9 + | +LL | let try_result: Option<_> = try { + | --- while parsing this struct +LL | //~^ ERROR expected struct, variant or union type, found macro `try` +LL | let x = 5; //~ ERROR expected identifier, found keyword + | ^^^ expected identifier, found keyword + +error[E0574]: expected struct, variant or union type, found macro `try` + --> $DIR/try-block-in-edition2015.rs:14:33 + | +LL | let try_result: Option<_> = try { + | ^^^ did you mean `try!(...)`? + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0574`. diff --git a/src/test/ui/try-block-type-error.rs b/src/test/ui/try-block-type-error.rs new file mode 100644 index 00000000000..58b35e46302 --- /dev/null +++ b/src/test/ui/try-block-type-error.rs @@ -0,0 +1,28 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +#![feature(catch_expr)] + +fn foo() -> Option<()> { Some(()) } + +fn main() { + let _: Option = try { + foo()?; + 42 + //~^ ERROR type mismatch + }; + + let _: Option = try { + foo()?; + }; + //~^ ERROR type mismatch +} diff --git a/src/test/ui/try-block-type-error.stderr b/src/test/ui/try-block-type-error.stderr new file mode 100644 index 00000000000..3b67e92ec61 --- /dev/null +++ b/src/test/ui/try-block-type-error.stderr @@ -0,0 +1,24 @@ +error[E0271]: type mismatch resolving ` as std::ops::Try>::Ok == {integer}` + --> $DIR/try-block-type-error.rs:20:9 + | +LL | 42 + | ^^ + | | + | expected f32, found integral variable + | help: use a float literal: `42.0` + | + = note: expected type `f32` + found type `{integer}` + +error[E0271]: type mismatch resolving ` as std::ops::Try>::Ok == ()` + --> $DIR/try-block-type-error.rs:26:5 + | +LL | }; + | ^ expected i32, found () + | + = note: expected type `i32` + found type `()` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0271`. -- cgit 1.4.1-3-g733a5 From 817efc2489806b8188c2f5693fb3b0dcf9c76eb1 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 24 Jul 2018 17:55:36 -0700 Subject: Suggest `try` if someone uses `do catch` --- src/libsyntax/parse/parser.rs | 12 ++++++++++++ src/test/parse-fail/do-catch-suggests-try.rs | 17 +++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/test/parse-fail/do-catch-suggests-try.rs (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2b0cfd14a3d..ad57530474c 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2386,6 +2386,11 @@ impl<'a> Parser<'a> { BlockCheckMode::Unsafe(ast::UserProvided), attrs); } + 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::Try)); @@ -4406,6 +4411,13 @@ impl<'a> Parser<'a> { ) } + 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)) && diff --git a/src/test/parse-fail/do-catch-suggests-try.rs b/src/test/parse-fail/do-catch-suggests-try.rs new file mode 100644 index 00000000000..449135e69c3 --- /dev/null +++ b/src/test/parse-fail/do-catch-suggests-try.rs @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: -Z parse-only + +fn main() { + let _: Option<()> = do catch {}; + //~^ ERROR found removed `do catch` syntax + //~^^ HELP Following RFC #2388, the new non-placeholder syntax is `try` +} -- cgit 1.4.1-3-g733a5 From 9f683bed3dfa6516bbe81b6e58a9a8f2f00b1250 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 24 Jul 2018 18:03:25 -0700 Subject: Rename `catch_expr` feature to `try_blocks` --- .../src/language-features/catch-expr.md | 32 ---------------------- .../src/language-features/try-blocks.md | 32 ++++++++++++++++++++++ src/librustc/lib.rs | 1 - src/libsyntax/feature_gate.rs | 4 +-- src/test/compile-fail/try-block-bad-lifetime.rs | 2 +- src/test/compile-fail/try-block-bad-type.rs | 2 +- src/test/compile-fail/try-block-in-match.rs | 2 +- src/test/compile-fail/try-block-in-while.rs | 2 +- .../compile-fail/try-block-maybe-bad-lifetime.rs | 2 +- src/test/compile-fail/try-block-opt-init.rs | 2 +- src/test/run-pass/issue-45124.rs | 2 +- src/test/run-pass/try-block.rs | 2 +- .../ui/feature-gates/feature-gate-catch_expr.rs | 19 ------------- .../feature-gates/feature-gate-catch_expr.stderr | 15 ---------- .../ui/feature-gates/feature-gate-try_blocks.rs | 19 +++++++++++++ .../feature-gates/feature-gate-try_blocks.stderr | 15 ++++++++++ src/test/ui/try-block-type-error.rs | 2 +- 17 files changed, 77 insertions(+), 78 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/catch-expr.md create mode 100644 src/doc/unstable-book/src/language-features/try-blocks.md delete mode 100644 src/test/ui/feature-gates/feature-gate-catch_expr.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-catch_expr.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-try_blocks.rs create mode 100644 src/test/ui/feature-gates/feature-gate-try_blocks.stderr (limited to 'src/libsyntax') diff --git a/src/doc/unstable-book/src/language-features/catch-expr.md b/src/doc/unstable-book/src/language-features/catch-expr.md deleted file mode 100644 index 5295d642aa6..00000000000 --- a/src/doc/unstable-book/src/language-features/catch-expr.md +++ /dev/null @@ -1,32 +0,0 @@ -# `catch_expr` - -The tracking issue for this feature is: [#31436] - -[#31436]: https://github.com/rust-lang/rust/issues/31436 - ------------------------- - -The `catch_expr` feature adds support for `try` blocks. A `try` -block creates a new scope one can use the `?` operator in. - -```rust,ignore -// This code needs the 2018 edition - -#![feature(catch_expr)] - -use std::num::ParseIntError; - -let result: Result = try { - "1".parse::()? - + "2".parse::()? - + "3".parse::()? -}; -assert_eq!(result, Ok(6)); - -let result: Result = try { - "1".parse::()? - + "foo".parse::()? - + "3".parse::()? -}; -assert!(result.is_err()); -``` diff --git a/src/doc/unstable-book/src/language-features/try-blocks.md b/src/doc/unstable-book/src/language-features/try-blocks.md new file mode 100644 index 00000000000..866b37a39a7 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/try-blocks.md @@ -0,0 +1,32 @@ +# `try_blocks` + +The tracking issue for this feature is: [#31436] + +[#31436]: https://github.com/rust-lang/rust/issues/31436 + +------------------------ + +The `try_blocks` feature adds support for `try` blocks. A `try` +block creates a new scope one can use the `?` operator in. + +```rust,ignore +// This code needs the 2018 edition + +#![feature(try_blocks)] + +use std::num::ParseIntError; + +let result: Result = try { + "1".parse::()? + + "2".parse::()? + + "3".parse::()? +}; +assert_eq!(result, Ok(6)); + +let result: Result = try { + "1".parse::()? + + "foo".parse::()? + + "3".parse::()? +}; +assert!(result.is_err()); +``` diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index b6f4bd6dc40..7e937c5fc05 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -65,7 +65,6 @@ #![feature(trace_macros)] #![feature(trusted_len)] #![feature(vec_remove_item)] -#![feature(catch_expr)] #![feature(step_trait)] #![feature(integer_atomics)] #![feature(test)] diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index f796c0e2e53..c89efcf4ba0 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -331,7 +331,7 @@ declare_features! ( (active, abi_x86_interrupt, "1.17.0", Some(40180), None), // Allows the `try {...}` expression - (active, catch_expr, "1.17.0", Some(31436), None), + (active, try_blocks, "1.29.0", Some(31436), None), // Used to preserve symbols (see llvm.used) (active, used, "1.18.0", Some(40289), None), @@ -1735,7 +1735,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { "yield syntax is experimental"); } ast::ExprKind::TryBlock(_) => { - gate_feature_post!(&self, catch_expr, e.span, "`try` expression is experimental"); + 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/test/compile-fail/try-block-bad-lifetime.rs b/src/test/compile-fail/try-block-bad-lifetime.rs index 8dfd8545af7..61de6baecd7 100644 --- a/src/test/compile-fail/try-block-bad-lifetime.rs +++ b/src/test/compile-fail/try-block-bad-lifetime.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] // This test checks that borrows made and returned inside try blocks are properly constrained pub fn main() { diff --git a/src/test/compile-fail/try-block-bad-type.rs b/src/test/compile-fail/try-block-bad-type.rs index 9e555df8535..a984b63af45 100644 --- a/src/test/compile-fail/try-block-bad-type.rs +++ b/src/test/compile-fail/try-block-bad-type.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] pub fn main() { let res: Result = try { diff --git a/src/test/compile-fail/try-block-in-match.rs b/src/test/compile-fail/try-block-in-match.rs index 1920caa548f..d10149126ee 100644 --- a/src/test/compile-fail/try-block-in-match.rs +++ b/src/test/compile-fail/try-block-in-match.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] fn main() { match try { false } { _ => {} } //~ ERROR expected expression, found reserved keyword `try` diff --git a/src/test/compile-fail/try-block-in-while.rs b/src/test/compile-fail/try-block-in-while.rs index fc1c0897614..b531267a55b 100644 --- a/src/test/compile-fail/try-block-in-while.rs +++ b/src/test/compile-fail/try-block-in-while.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] fn main() { while try { false } {} //~ ERROR expected expression, found reserved keyword `try` diff --git a/src/test/compile-fail/try-block-maybe-bad-lifetime.rs b/src/test/compile-fail/try-block-maybe-bad-lifetime.rs index db37a397c16..297540bb1e7 100644 --- a/src/test/compile-fail/try-block-maybe-bad-lifetime.rs +++ b/src/test/compile-fail/try-block-maybe-bad-lifetime.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] // This test checks that borrows made and returned inside try blocks are properly constrained pub fn main() { diff --git a/src/test/compile-fail/try-block-opt-init.rs b/src/test/compile-fail/try-block-opt-init.rs index 14544c6ea0c..476fec20220 100644 --- a/src/test/compile-fail/try-block-opt-init.rs +++ b/src/test/compile-fail/try-block-opt-init.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] fn use_val(_x: T) {} diff --git a/src/test/run-pass/issue-45124.rs b/src/test/run-pass/issue-45124.rs index 5f47cc8d7d5..cb79eda8b07 100644 --- a/src/test/run-pass/issue-45124.rs +++ b/src/test/run-pass/issue-45124.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] fn main() { let mut a = 0; diff --git a/src/test/run-pass/try-block.rs b/src/test/run-pass/try-block.rs index f2b017e94f0..a7e7cc20620 100644 --- a/src/test/run-pass/try-block.rs +++ b/src/test/run-pass/try-block.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] struct catch {} diff --git a/src/test/ui/feature-gates/feature-gate-catch_expr.rs b/src/test/ui/feature-gates/feature-gate-catch_expr.rs deleted file mode 100644 index 6536280c71f..00000000000 --- a/src/test/ui/feature-gates/feature-gate-catch_expr.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// compile-flags: --edition 2018 - -pub fn main() { - let try_result: Option<_> = try { //~ ERROR `try` expression is experimental - let x = 5; - x - }; - assert_eq!(try_result, Some(5)); -} diff --git a/src/test/ui/feature-gates/feature-gate-catch_expr.stderr b/src/test/ui/feature-gates/feature-gate-catch_expr.stderr deleted file mode 100644 index 4842215d51a..00000000000 --- a/src/test/ui/feature-gates/feature-gate-catch_expr.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0658]: `try` expression is experimental (see issue #31436) - --> $DIR/feature-gate-catch_expr.rs:14:33 - | -LL | let try_result: Option<_> = try { //~ ERROR `try` expression is experimental - | _________________________________^ -LL | | let x = 5; -LL | | x -LL | | }; - | |_____^ - | - = help: add #![feature(catch_expr)] to the crate attributes to enable - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-try_blocks.rs b/src/test/ui/feature-gates/feature-gate-try_blocks.rs new file mode 100644 index 00000000000..6536280c71f --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-try_blocks.rs @@ -0,0 +1,19 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// compile-flags: --edition 2018 + +pub fn main() { + let try_result: Option<_> = try { //~ ERROR `try` expression is experimental + let x = 5; + x + }; + assert_eq!(try_result, Some(5)); +} diff --git a/src/test/ui/feature-gates/feature-gate-try_blocks.stderr b/src/test/ui/feature-gates/feature-gate-try_blocks.stderr new file mode 100644 index 00000000000..29ef2f87b9d --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-try_blocks.stderr @@ -0,0 +1,15 @@ +error[E0658]: `try` expression is experimental (see issue #31436) + --> $DIR/feature-gate-try_blocks.rs:14:33 + | +LL | let try_result: Option<_> = try { //~ ERROR `try` expression is experimental + | _________________________________^ +LL | | let x = 5; +LL | | x +LL | | }; + | |_____^ + | + = help: add #![feature(try_blocks)] to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/try-block-type-error.rs b/src/test/ui/try-block-type-error.rs index 58b35e46302..6a69cff4883 100644 --- a/src/test/ui/try-block-type-error.rs +++ b/src/test/ui/try-block-type-error.rs @@ -10,7 +10,7 @@ // compile-flags: --edition 2018 -#![feature(catch_expr)] +#![feature(try_blocks)] fn foo() -> Option<()> { Some(()) } -- cgit 1.4.1-3-g733a5 From 009547141729b6d66f721065820edf9ddbde4831 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 19 Aug 2018 17:51:02 -0700 Subject: Switch out another use of `do catch` --- src/libsyntax/lib.rs | 2 +- src/libsyntax/parse/parser.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 0a42325d2b6..0b9d53b5af4 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/parser.rs b/src/libsyntax/parse/parser.rs index ad57530474c..b766fbd0d71 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -1756,9 +1756,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()?) -- cgit 1.4.1-3-g733a5