diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 3cf2d8f8ac1ef..5746bab4e04b8 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -421,8 +421,7 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool { fn or_pat_mode(edition: Edition) -> OrPatNonterminalMode { match edition { Edition::Edition2015 | Edition::Edition2018 => OrPatNonterminalMode::NoTopAlt, - // FIXME(mark-i-m): uncomment this when edition 2021 machinery is added. - // Edition::Edition2021 => OrPatNonterminalMode::TopPat, + Edition::Edition2021 => OrPatNonterminalMode::TopPat, } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index eed3e9947b2aa..45c3e67bd0bfc 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -15,6 +15,7 @@ use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, DiagnosticBuilder, PResult}; +use rustc_span::edition::LATEST_STABLE_EDITION; use rustc_span::source_map::{self, Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Pos}; @@ -2098,8 +2099,8 @@ impl<'a> Parser<'a> { let mut async_block_err = |e: &mut DiagnosticBuilder<'_>, span: Span| { recover_async = true; - e.span_label(span, "`async` blocks are only allowed in the 2018 edition"); - e.help("set `edition = \"2018\"` in `Cargo.toml`"); + e.span_label(span, "`async` blocks are only allowed in Rust 2018 or later"); + e.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION)); e.note("for more on editions, read https://doc.rust-lang.org/edition-guide"); }; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 634cce403df96..7b72a8f2c6dbe 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -16,7 +16,7 @@ use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, Visibility use rustc_ast::{MacArgs, MacCall, MacDelimiter}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, PResult, StashKey}; -use rustc_span::edition::Edition; +use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; use rustc_span::source_map::{self, Span}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1667,9 +1667,9 @@ impl<'a> Parser<'a> { fn ban_async_in_2015(&self, span: Span) { if span.rust_2015() { let diag = self.diagnostic(); - struct_span_err!(diag, span, E0670, "`async fn` is not permitted in the 2015 edition") - .span_label(span, "to use `async fn`, switch to Rust 2018") - .help("set `edition = \"2018\"` in `Cargo.toml`") + struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015") + .span_label(span, "to use `async fn`, switch to Rust 2018 or later") + .help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION)) .note("for more on editions, read https://doc.rust-lang.org/edition-guide") .emit(); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 68f59baffce17..03b03448ee5bd 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -180,7 +180,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ( format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), if path_str == "async" && expected.starts_with("struct") { - "`async` blocks are only allowed in the 2018 edition".to_string() + "`async` blocks are only allowed in Rust 2018 or later".to_string() } else { format!("not found in {}", mod_str) }, @@ -904,7 +904,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { Applicability::MaybeIncorrect, ); if path_str == "try" && span.rust_2015() { - err.note("if you want the `try` keyword, you need to be in the 2018 edition"); + err.note("if you want the `try` keyword, you need Rust 2018 or later"); } } (Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => { diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index c9ddcbdb5f5cc..62859f4bef430 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1308,12 +1308,11 @@ fn parse_crate_edition(matches: &getopts::Matches) -> Edition { None => DEFAULT_EDITION, }; - if !edition.is_stable() && !nightly_options::match_is_nightly_build(matches) { + if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) { early_error( ErrorOutputType::default(), &format!( - "edition {} is unstable and only \ - available for nightly builds of rustc.", + "edition {} is unstable and only available with -Z unstable-options.", edition, ), ) diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 75faab12e3e12..3a420f5f9def7 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1076,6 +1076,11 @@ impl Session { self.opts.edition >= Edition::Edition2018 } + /// Are we allowed to use features from the Rust 2021 edition? + pub fn rust_2021(&self) -> bool { + self.opts.edition >= Edition::Edition2021 + } + pub fn edition(&self) -> Edition { self.opts.edition } diff --git a/compiler/rustc_span/src/edition.rs b/compiler/rustc_span/src/edition.rs index 4d0c92f51d7ca..3511e2ea1c0e4 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -13,6 +13,8 @@ pub enum Edition { Edition2015, /// The 2018 edition Edition2018, + /// The 2021 ediiton + Edition2021, // when adding new editions, be sure to update: // // - Update the `ALL_EDITIONS` const @@ -22,17 +24,21 @@ pub enum Edition { } // must be in order from oldest to newest -pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018]; +pub const ALL_EDITIONS: &[Edition] = + &[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021]; -pub const EDITION_NAME_LIST: &str = "2015|2018"; +pub const EDITION_NAME_LIST: &str = "2015|2018|2021"; pub const DEFAULT_EDITION: Edition = Edition::Edition2015; +pub const LATEST_STABLE_EDITION: Edition = Edition::Edition2018; + impl fmt::Display for Edition { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let s = match *self { Edition::Edition2015 => "2015", Edition::Edition2018 => "2018", + Edition::Edition2021 => "2021", }; write!(f, "{}", s) } @@ -43,6 +49,7 @@ impl Edition { match *self { Edition::Edition2015 => "rust_2015_compatibility", Edition::Edition2018 => "rust_2018_compatibility", + Edition::Edition2021 => "rust_2021_compatibility", } } @@ -50,6 +57,7 @@ impl Edition { match *self { Edition::Edition2015 => sym::rust_2015_preview, Edition::Edition2018 => sym::rust_2018_preview, + Edition::Edition2021 => sym::rust_2021_preview, } } @@ -57,6 +65,7 @@ impl Edition { match *self { Edition::Edition2015 => true, Edition::Edition2018 => true, + Edition::Edition2021 => false, } } } @@ -67,6 +76,7 @@ impl FromStr for Edition { match s { "2015" => Ok(Edition::Edition2015), "2018" => Ok(Edition::Edition2018), + "2021" => Ok(Edition::Edition2021), _ => Err(()), } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index f63a73acbf4ba..33c830c0f5fb3 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -469,6 +469,11 @@ impl Span { self.edition() >= edition::Edition::Edition2018 } + #[inline] + pub fn rust_2021(&self) -> bool { + self.edition() >= edition::Edition::Edition2021 + } + /// Returns the source callee. /// /// Returns `None` if the supplied span has no expansion trace, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 99a523c3f3bb4..a52742fb1dfe8 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -920,6 +920,7 @@ symbols! { rust, rust_2015_preview, rust_2018_preview, + rust_2021_preview, rust_begin_unwind, rust_eh_catch_typeinfo, rust_eh_personality, diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index ec0e039b5d29d..b0163c1e46aae 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -38,6 +38,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; use rustc_middle::ty::Ty; use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{AdtKind, Visibility}; +use rustc_span::edition::LATEST_STABLE_EDITION; use rustc_span::hygiene::DesugaringKind; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::source_map::Span; @@ -1637,8 +1638,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if field.name == kw::Await { // We know by construction that `.await` is either on Rust 2015 // or results in `ExprKind::Await`. Suggest switching the edition to 2018. - err.note("to `.await` a `Future`, switch to Rust 2018"); - err.help("set `edition = \"2018\"` in `Cargo.toml`"); + err.note("to `.await` a `Future`, switch to Rust 2018 or later"); + err.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION)); err.note("for more on editions, read https://doc.rust-lang.org/edition-guide"); } diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.rs b/src/test/ui/async-await/edition-deny-async-fns-2015.rs index 5d2d186137e16..e5dc9c8a5fee8 100644 --- a/src/test/ui/async-await/edition-deny-async-fns-2015.rs +++ b/src/test/ui/async-await/edition-deny-async-fns-2015.rs @@ -1,21 +1,21 @@ // edition:2015 -async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition +async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015 -fn baz() { async fn foo() {} } //~ ERROR `async fn` is not permitted in the 2015 edition +fn baz() { async fn foo() {} } //~ ERROR `async fn` is not permitted in Rust 2015 -async fn async_baz() { //~ ERROR `async fn` is not permitted in the 2015 edition - async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition +async fn async_baz() { //~ ERROR `async fn` is not permitted in Rust 2015 + async fn bar() {} //~ ERROR `async fn` is not permitted in Rust 2015 } struct Foo {} impl Foo { - async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition + async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015 } trait Bar { - async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition + async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015 //~^ ERROR functions in traits cannot be declared `async` } @@ -23,16 +23,16 @@ fn main() { macro_rules! accept_item { ($x:item) => {} } accept_item! { - async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition + async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015 } accept_item! { impl Foo { - async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition + async fn bar() {} //~ ERROR `async fn` is not permitted in Rust 2015 } } let inside_closure = || { - async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition + async fn bar() {} //~ ERROR `async fn` is not permitted in Rust 2015 }; } diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr index 8bffeb2131dec..43364a8e85896 100644 --- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr +++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr @@ -1,80 +1,80 @@ -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:3:1 | LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:5:12 | LL | fn baz() { async fn foo() {} } - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:7:1 | LL | async fn async_baz() { - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:8:5 | LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:14:5 | LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:18:5 | LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:36:9 | LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:26:9 | LL | async fn foo() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/edition-deny-async-fns-2015.rs:31:13 | LL | async fn bar() {} - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide diff --git a/src/test/ui/async-await/suggest-switching-edition-on-await.stderr b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr index 695d7dd59fb4f..9ac2bc5cc8964 100644 --- a/src/test/ui/async-await/suggest-switching-edition-on-await.stderr +++ b/src/test/ui/async-await/suggest-switching-edition-on-await.stderr @@ -4,7 +4,7 @@ error[E0609]: no field `await` on type `await_on_struct_missing::S` LL | x.await; | ^^^^^ unknown field | - = note: to `.await` a `Future`, switch to Rust 2018 + = note: to `.await` a `Future`, switch to Rust 2018 or later = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide @@ -14,7 +14,7 @@ error[E0609]: no field `await` on type `await_on_struct_similar::S` LL | x.await; | ^^^^^ help: a field with a similar name exists: `awai` | - = note: to `.await` a `Future`, switch to Rust 2018 + = note: to `.await` a `Future`, switch to Rust 2018 or later = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide @@ -24,7 +24,7 @@ error[E0609]: no field `await` on type `Pin<&mut dyn Future>` LL | x.await; | ^^^^^ unknown field | - = note: to `.await` a `Future`, switch to Rust 2018 + = note: to `.await` a `Future`, switch to Rust 2018 or later = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide @@ -34,7 +34,7 @@ error[E0609]: no field `await` on type `impl Future` LL | x.await; | ^^^^^ | - = note: to `.await` a `Future`, switch to Rust 2018 + = note: to `.await` a `Future`, switch to Rust 2018 or later = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide diff --git a/src/test/ui/editions/async-block-2015.rs b/src/test/ui/editions/async-block-2015.rs index 985606a6f2545..92eae9e3c14f8 100644 --- a/src/test/ui/editions/async-block-2015.rs +++ b/src/test/ui/editions/async-block-2015.rs @@ -1,13 +1,13 @@ async fn foo() { -//~^ ERROR `async fn` is not permitted in the 2015 edition -//~| NOTE to use `async fn`, switch to Rust 2018 +//~^ ERROR `async fn` is not permitted in Rust 2015 +//~| NOTE to use `async fn`, switch to Rust 2018 or later //~| HELP set `edition = "2018"` in `Cargo.toml` //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide let x = async {}; //~^ ERROR cannot find struct, variant or union type `async` in this scope - //~| NOTE `async` blocks are only allowed in the 2018 edition - let y = async { //~ NOTE `async` blocks are only allowed in the 2018 edition + //~| NOTE `async` blocks are only allowed in Rust 2018 or later + let y = async { //~ NOTE `async` blocks are only allowed in Rust 2018 or later let x = 42; //~^ ERROR expected identifier, found keyword `let` //~| NOTE expected identifier, found keyword @@ -15,7 +15,7 @@ async fn foo() { //~| NOTE for more on editions, read https://doc.rust-lang.org/edition-guide 42 }; - let z = async { //~ NOTE `async` blocks are only allowed in the 2018 edition + let z = async { //~ NOTE `async` blocks are only allowed in Rust 2018 or later 42 //~^ ERROR expected identifier, found `42` //~| NOTE expected identifier diff --git a/src/test/ui/editions/async-block-2015.stderr b/src/test/ui/editions/async-block-2015.stderr index 8e5e5d8bfab9a..e42747c804c71 100644 --- a/src/test/ui/editions/async-block-2015.stderr +++ b/src/test/ui/editions/async-block-2015.stderr @@ -1,8 +1,8 @@ -error[E0670]: `async fn` is not permitted in the 2015 edition +error[E0670]: `async fn` is not permitted in Rust 2015 --> $DIR/async-block-2015.rs:1:1 | LL | async fn foo() { - | ^^^^^ to use `async fn`, switch to Rust 2018 + | ^^^^^ to use `async fn`, switch to Rust 2018 or later | = help: set `edition = "2018"` in `Cargo.toml` = note: for more on editions, read https://doc.rust-lang.org/edition-guide @@ -11,7 +11,7 @@ error: expected identifier, found keyword `let` --> $DIR/async-block-2015.rs:11:9 | LL | let y = async { - | ----- `async` blocks are only allowed in the 2018 edition + | ----- `async` blocks are only allowed in Rust 2018 or later LL | let x = 42; | ^^^ expected identifier, found keyword | @@ -22,7 +22,7 @@ error: expected identifier, found `42` --> $DIR/async-block-2015.rs:19:9 | LL | let z = async { - | ----- `async` blocks are only allowed in the 2018 edition + | ----- `async` blocks are only allowed in Rust 2018 or later LL | 42 | ^^ expected identifier | @@ -33,7 +33,7 @@ error[E0422]: cannot find struct, variant or union type `async` in this scope --> $DIR/async-block-2015.rs:7:13 | LL | let x = async {}; - | ^^^^^ `async` blocks are only allowed in the 2018 edition + | ^^^^^ `async` blocks are only allowed in Rust 2018 or later error: aborting due to 4 previous errors diff --git a/src/test/ui/hello2021.rs b/src/test/ui/hello2021.rs new file mode 100644 index 0000000000000..738f151b0f60b --- /dev/null +++ b/src/test/ui/hello2021.rs @@ -0,0 +1,7 @@ +// run-pass +// edition:2021 +// compile-flags: -Zunstable-options + +fn main() { + println!("hello, 2021"); +} diff --git a/src/test/ui/try-block/try-block-in-edition2015.stderr b/src/test/ui/try-block/try-block-in-edition2015.stderr index 78cdfb2cc7f04..0f3c14b1386e7 100644 --- a/src/test/ui/try-block/try-block-in-edition2015.stderr +++ b/src/test/ui/try-block/try-block-in-edition2015.stderr @@ -13,7 +13,7 @@ error[E0574]: expected struct, variant or union type, found macro `try` LL | let try_result: Option<_> = try { | ^^^ not a struct, variant or union type | - = note: if you want the `try` keyword, you need to be in the 2018 edition + = note: if you want the `try` keyword, you need Rust 2018 or later help: use `!` to invoke the macro | LL | let try_result: Option<_> = try! {