From f16ef7d7ce0357d63435201ae51e2c0a6916e07d Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 30 Dec 2020 14:33:46 +0100 Subject: [PATCH] Add edition 2021. --- compiler/rustc_parse/src/parser/expr.rs | 5 +++-- compiler/rustc_parse/src/parser/item.rs | 6 +++--- compiler/rustc_session/src/session.rs | 5 +++++ compiler/rustc_span/src/edition.rs | 14 ++++++++++++-- compiler/rustc_span/src/lib.rs | 5 +++++ compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_typeck/src/check/expr.rs | 5 +++-- .../edition-deny-async-fns-2015.stderr | 18 +++++++++--------- .../suggest-switching-edition-on-await.stderr | 8 ++++---- src/test/ui/editions/async-block-2015.rs | 6 +++--- src/test/ui/editions/async-block-2015.stderr | 6 +++--- src/test/ui/hello2021.rs | 6 ++++++ 12 files changed, 57 insertions(+), 28 deletions(-) create mode 100644 src/test/ui/hello2021.rs diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b147f42fada25..40210f747ffb8 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}; @@ -2108,8 +2109,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 edition 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 c6669f0468296..6d79a6ac09cbb 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}; @@ -1668,8 +1668,8 @@ impl<'a> Parser<'a> { 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`") + .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_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 efbb0a23a6f01..a9200dd7dfd6e 100644 --- a/compiler/rustc_span/src/edition.rs +++ b/compiler/rustc_span/src/edition.rs @@ -20,20 +20,26 @@ pub enum Edition { Edition2015, /// The 2018 edition Edition2018, + /// The 2021 ediiton + Edition2021, } // 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) } @@ -44,6 +50,7 @@ impl Edition { match *self { Edition::Edition2015 => "rust_2015_compatibility", Edition::Edition2018 => "rust_2018_compatibility", + Edition::Edition2021 => "rust_2021_compatibility", } } @@ -51,6 +58,7 @@ impl Edition { match *self { Edition::Edition2015 => sym::rust_2015_preview, Edition::Edition2018 => sym::rust_2018_preview, + Edition::Edition2021 => sym::rust_2021_preview, } } @@ -58,6 +66,7 @@ impl Edition { match *self { Edition::Edition2015 => true, Edition::Edition2018 => true, + Edition::Edition2021 => false, } } } @@ -68,6 +77,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 8009530717566..99f01062545a7 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -481,6 +481,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 382b7a4f2db71..b040a70437d9e 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -923,6 +923,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 93eb2cfc72a80..8197d02ec594b 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.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr index 8bffeb2131dec..39bc8e7be8f9f 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 @@ -2,7 +2,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 @@ -11,7 +11,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 @@ -20,7 +20,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 @@ -29,7 +29,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 @@ -38,7 +38,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 @@ -47,7 +47,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 @@ -56,7 +56,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 @@ -65,7 +65,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 @@ -74,7 +74,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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..b35cc1564b3d9 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 +//~| 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 + let y = async { //~ NOTE `async` blocks are only allowed in edition 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 edition 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..d65761d79ff2b 100644 --- a/src/test/ui/editions/async-block-2015.stderr +++ b/src/test/ui/editions/async-block-2015.stderr @@ -2,7 +2,7 @@ error[E0670]: `async fn` is not permitted in the 2015 edition --> $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 edition 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 edition 2018 or later LL | 42 | ^^ expected identifier | diff --git a/src/test/ui/hello2021.rs b/src/test/ui/hello2021.rs new file mode 100644 index 0000000000000..134d8af5bfb8a --- /dev/null +++ b/src/test/ui/hello2021.rs @@ -0,0 +1,6 @@ +// run-pass +// edition:2021 + +fn main() { + println!("hello, 2021"); +}