Skip to content

Commit

Permalink
Auto merge of #79576 - m-ou-se:2021, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
Add edition 2021.

:fireworks: Happy new ~~year~~ Rust. :champagne:

This adds --edition=2021, and updates suggestions about 2018 to say "2018 *or later*".

Related Cargo PR: rust-lang/cargo#8922

---

Edit: This adds the new edition as *unstable*. Without `-Z unstable-options`, `--edition=2021` results in:
```
$ rustc --edition=2021
error: edition 2021 is unstable and only available with -Z unstable-options.
```
  • Loading branch information
bors committed Jan 1, 2021
2 parents 99ad5a1 + 3cbdbe8 commit f8ab56b
Show file tree
Hide file tree
Showing 17 changed files with 87 additions and 59 deletions.
3 changes: 1 addition & 2 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,7 @@ impl NonterminalKind {
Edition::Edition2015 | Edition::Edition2018 => {
NonterminalKind::Pat2018 { inferred: true }
}
// FIXME(mark-i-m): uncomment when 2021 machinery is available.
//Edition::Edition2021 => NonterminalKind::Pat2021{inferred:true},
Edition::Edition2021 => NonterminalKind::Pat2021 { inferred: true },
},
sym::pat2018 => NonterminalKind::Pat2018 { inferred: false },
sym::pat2021 => NonterminalKind::Pat2021 { inferred: false },
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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 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");
};

Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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();
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_resolve/src/late/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
},
Expand Down Expand Up @@ -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(_)) => {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
),
)
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
14 changes: 12 additions & 2 deletions compiler/rustc_span/src/edition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -44,20 +50,23 @@ impl Edition {
match *self {
Edition::Edition2015 => "rust_2015_compatibility",
Edition::Edition2018 => "rust_2018_compatibility",
Edition::Edition2021 => "rust_2021_compatibility",
}
}

pub fn feature_name(&self) -> Symbol {
match *self {
Edition::Edition2015 => sym::rust_2015_preview,
Edition::Edition2018 => sym::rust_2018_preview,
Edition::Edition2021 => sym::rust_2021_preview,
}
}

pub fn is_stable(&self) -> bool {
match *self {
Edition::Edition2015 => true,
Edition::Edition2018 => true,
Edition::Edition2021 => false,
}
}
}
Expand All @@ -68,6 +77,7 @@ impl FromStr for Edition {
match s {
"2015" => Ok(Edition::Edition2015),
"2018" => Ok(Edition::Edition2018),
"2021" => Ok(Edition::Edition2021),
_ => Err(()),
}
}
Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_span/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1637,8 +1638,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if field.name == kw::Await {
// We know by construction that `<expr>.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");
}

Expand Down
18 changes: 9 additions & 9 deletions src/test/ui/async-await/edition-deny-async-fns-2015.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
// 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`
}

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
};
}
36 changes: 18 additions & 18 deletions src/test/ui/async-await/edition-deny-async-fns-2015.stderr
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand All @@ -24,7 +24,7 @@ error[E0609]: no field `await` on type `Pin<&mut dyn Future<Output = ()>>`
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

Expand All @@ -34,7 +34,7 @@ error[E0609]: no field `await` on type `impl Future<Output = ()>`
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

Expand Down
Loading

0 comments on commit f8ab56b

Please sign in to comment.