Skip to content

Commit 72b0df9

Browse files
authored
Rollup merge of rust-lang#79576 - m-ou-se:2021, r=Mark-Simulacrum
Add edition 2021. :fireworks: Happy new ~~year~~ edition. :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. ```
2 parents b251612 + cfee9fb commit 72b0df9

File tree

17 files changed

+87
-59
lines changed

17 files changed

+87
-59
lines changed

compiler/rustc_expand/src/mbe/macro_parser.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,7 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
421421
fn or_pat_mode(edition: Edition) -> OrPatNonterminalMode {
422422
match edition {
423423
Edition::Edition2015 | Edition::Edition2018 => OrPatNonterminalMode::NoTopAlt,
424-
// FIXME(mark-i-m): uncomment this when edition 2021 machinery is added.
425-
// Edition::Edition2021 => OrPatNonterminalMode::TopPat,
424+
Edition::Edition2021 => OrPatNonterminalMode::TopPat,
426425
}
427426
}
428427

compiler/rustc_parse/src/parser/expr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty
1515
use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
1616
use rustc_ast_pretty::pprust;
1717
use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
18+
use rustc_span::edition::LATEST_STABLE_EDITION;
1819
use rustc_span::source_map::{self, Span, Spanned};
1920
use rustc_span::symbol::{kw, sym, Ident, Symbol};
2021
use rustc_span::{BytePos, Pos};
@@ -2098,8 +2099,8 @@ impl<'a> Parser<'a> {
20982099

20992100
let mut async_block_err = |e: &mut DiagnosticBuilder<'_>, span: Span| {
21002101
recover_async = true;
2101-
e.span_label(span, "`async` blocks are only allowed in the 2018 edition");
2102-
e.help("set `edition = \"2018\"` in `Cargo.toml`");
2102+
e.span_label(span, "`async` blocks are only allowed in Rust 2018 or later");
2103+
e.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
21032104
e.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
21042105
};
21052106

compiler/rustc_parse/src/parser/item.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, Visibility
1616
use rustc_ast::{MacArgs, MacCall, MacDelimiter};
1717
use rustc_ast_pretty::pprust;
1818
use rustc_errors::{struct_span_err, Applicability, PResult, StashKey};
19-
use rustc_span::edition::Edition;
19+
use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
2020
use rustc_span::source_map::{self, Span};
2121
use rustc_span::symbol::{kw, sym, Ident, Symbol};
2222

@@ -1667,9 +1667,9 @@ impl<'a> Parser<'a> {
16671667
fn ban_async_in_2015(&self, span: Span) {
16681668
if span.rust_2015() {
16691669
let diag = self.diagnostic();
1670-
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in the 2015 edition")
1671-
.span_label(span, "to use `async fn`, switch to Rust 2018")
1672-
.help("set `edition = \"2018\"` in `Cargo.toml`")
1670+
struct_span_err!(diag, span, E0670, "`async fn` is not permitted in Rust 2015")
1671+
.span_label(span, "to use `async fn`, switch to Rust 2018 or later")
1672+
.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION))
16731673
.note("for more on editions, read https://doc.rust-lang.org/edition-guide")
16741674
.emit();
16751675
}

compiler/rustc_resolve/src/late/diagnostics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
180180
(
181181
format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str),
182182
if path_str == "async" && expected.starts_with("struct") {
183-
"`async` blocks are only allowed in the 2018 edition".to_string()
183+
"`async` blocks are only allowed in Rust 2018 or later".to_string()
184184
} else {
185185
format!("not found in {}", mod_str)
186186
},
@@ -904,7 +904,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
904904
Applicability::MaybeIncorrect,
905905
);
906906
if path_str == "try" && span.rust_2015() {
907-
err.note("if you want the `try` keyword, you need to be in the 2018 edition");
907+
err.note("if you want the `try` keyword, you need Rust 2018 or later");
908908
}
909909
}
910910
(Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => {

compiler/rustc_session/src/config.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1308,12 +1308,11 @@ fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
13081308
None => DEFAULT_EDITION,
13091309
};
13101310

1311-
if !edition.is_stable() && !nightly_options::match_is_nightly_build(matches) {
1311+
if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
13121312
early_error(
13131313
ErrorOutputType::default(),
13141314
&format!(
1315-
"edition {} is unstable and only \
1316-
available for nightly builds of rustc.",
1315+
"edition {} is unstable and only available with -Z unstable-options.",
13171316
edition,
13181317
),
13191318
)

compiler/rustc_session/src/session.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,11 @@ impl Session {
10761076
self.opts.edition >= Edition::Edition2018
10771077
}
10781078

1079+
/// Are we allowed to use features from the Rust 2021 edition?
1080+
pub fn rust_2021(&self) -> bool {
1081+
self.opts.edition >= Edition::Edition2021
1082+
}
1083+
10791084
pub fn edition(&self) -> Edition {
10801085
self.opts.edition
10811086
}

compiler/rustc_span/src/edition.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ pub enum Edition {
1313
Edition2015,
1414
/// The 2018 edition
1515
Edition2018,
16+
/// The 2021 ediiton
17+
Edition2021,
1618
// when adding new editions, be sure to update:
1719
//
1820
// - Update the `ALL_EDITIONS` const
@@ -22,17 +24,21 @@ pub enum Edition {
2224
}
2325

2426
// must be in order from oldest to newest
25-
pub const ALL_EDITIONS: &[Edition] = &[Edition::Edition2015, Edition::Edition2018];
27+
pub const ALL_EDITIONS: &[Edition] =
28+
&[Edition::Edition2015, Edition::Edition2018, Edition::Edition2021];
2629

27-
pub const EDITION_NAME_LIST: &str = "2015|2018";
30+
pub const EDITION_NAME_LIST: &str = "2015|2018|2021";
2831

2932
pub const DEFAULT_EDITION: Edition = Edition::Edition2015;
3033

34+
pub const LATEST_STABLE_EDITION: Edition = Edition::Edition2018;
35+
3136
impl fmt::Display for Edition {
3237
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3338
let s = match *self {
3439
Edition::Edition2015 => "2015",
3540
Edition::Edition2018 => "2018",
41+
Edition::Edition2021 => "2021",
3642
};
3743
write!(f, "{}", s)
3844
}
@@ -43,20 +49,23 @@ impl Edition {
4349
match *self {
4450
Edition::Edition2015 => "rust_2015_compatibility",
4551
Edition::Edition2018 => "rust_2018_compatibility",
52+
Edition::Edition2021 => "rust_2021_compatibility",
4653
}
4754
}
4855

4956
pub fn feature_name(&self) -> Symbol {
5057
match *self {
5158
Edition::Edition2015 => sym::rust_2015_preview,
5259
Edition::Edition2018 => sym::rust_2018_preview,
60+
Edition::Edition2021 => sym::rust_2021_preview,
5361
}
5462
}
5563

5664
pub fn is_stable(&self) -> bool {
5765
match *self {
5866
Edition::Edition2015 => true,
5967
Edition::Edition2018 => true,
68+
Edition::Edition2021 => false,
6069
}
6170
}
6271
}
@@ -67,6 +76,7 @@ impl FromStr for Edition {
6776
match s {
6877
"2015" => Ok(Edition::Edition2015),
6978
"2018" => Ok(Edition::Edition2018),
79+
"2021" => Ok(Edition::Edition2021),
7080
_ => Err(()),
7181
}
7282
}

compiler/rustc_span/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,11 @@ impl Span {
469469
self.edition() >= edition::Edition::Edition2018
470470
}
471471

472+
#[inline]
473+
pub fn rust_2021(&self) -> bool {
474+
self.edition() >= edition::Edition::Edition2021
475+
}
476+
472477
/// Returns the source callee.
473478
///
474479
/// Returns `None` if the supplied span has no expansion trace,

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,7 @@ symbols! {
920920
rust,
921921
rust_2015_preview,
922922
rust_2018_preview,
923+
rust_2021_preview,
923924
rust_begin_unwind,
924925
rust_eh_catch_typeinfo,
925926
rust_eh_personality,

compiler/rustc_typeck/src/check/expr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
3838
use rustc_middle::ty::Ty;
3939
use rustc_middle::ty::TypeFoldable;
4040
use rustc_middle::ty::{AdtKind, Visibility};
41+
use rustc_span::edition::LATEST_STABLE_EDITION;
4142
use rustc_span::hygiene::DesugaringKind;
4243
use rustc_span::lev_distance::find_best_match_for_name;
4344
use rustc_span::source_map::Span;
@@ -1637,8 +1638,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16371638
if field.name == kw::Await {
16381639
// We know by construction that `<expr>.await` is either on Rust 2015
16391640
// or results in `ExprKind::Await`. Suggest switching the edition to 2018.
1640-
err.note("to `.await` a `Future`, switch to Rust 2018");
1641-
err.help("set `edition = \"2018\"` in `Cargo.toml`");
1641+
err.note("to `.await` a `Future`, switch to Rust 2018 or later");
1642+
err.help(&format!("set `edition = \"{}\"` in `Cargo.toml`", LATEST_STABLE_EDITION));
16421643
err.note("for more on editions, read https://doc.rust-lang.org/edition-guide");
16431644
}
16441645

Original file line numberDiff line numberDiff line change
@@ -1,38 +1,38 @@
11
// edition:2015
22

3-
async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
3+
async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
44

5-
fn baz() { async fn foo() {} } //~ ERROR `async fn` is not permitted in the 2015 edition
5+
fn baz() { async fn foo() {} } //~ ERROR `async fn` is not permitted in Rust 2015
66

7-
async fn async_baz() { //~ ERROR `async fn` is not permitted in the 2015 edition
8-
async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
7+
async fn async_baz() { //~ ERROR `async fn` is not permitted in Rust 2015
8+
async fn bar() {} //~ ERROR `async fn` is not permitted in Rust 2015
99
}
1010

1111
struct Foo {}
1212

1313
impl Foo {
14-
async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
14+
async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
1515
}
1616

1717
trait Bar {
18-
async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
18+
async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
1919
//~^ ERROR functions in traits cannot be declared `async`
2020
}
2121

2222
fn main() {
2323
macro_rules! accept_item { ($x:item) => {} }
2424

2525
accept_item! {
26-
async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition
26+
async fn foo() {} //~ ERROR `async fn` is not permitted in Rust 2015
2727
}
2828

2929
accept_item! {
3030
impl Foo {
31-
async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
31+
async fn bar() {} //~ ERROR `async fn` is not permitted in Rust 2015
3232
}
3333
}
3434

3535
let inside_closure = || {
36-
async fn bar() {} //~ ERROR `async fn` is not permitted in the 2015 edition
36+
async fn bar() {} //~ ERROR `async fn` is not permitted in Rust 2015
3737
};
3838
}

src/test/ui/async-await/edition-deny-async-fns-2015.stderr

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,80 @@
1-
error[E0670]: `async fn` is not permitted in the 2015 edition
1+
error[E0670]: `async fn` is not permitted in Rust 2015
22
--> $DIR/edition-deny-async-fns-2015.rs:3:1
33
|
44
LL | async fn foo() {}
5-
| ^^^^^ to use `async fn`, switch to Rust 2018
5+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
66
|
77
= help: set `edition = "2018"` in `Cargo.toml`
88
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
99

10-
error[E0670]: `async fn` is not permitted in the 2015 edition
10+
error[E0670]: `async fn` is not permitted in Rust 2015
1111
--> $DIR/edition-deny-async-fns-2015.rs:5:12
1212
|
1313
LL | fn baz() { async fn foo() {} }
14-
| ^^^^^ to use `async fn`, switch to Rust 2018
14+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
1515
|
1616
= help: set `edition = "2018"` in `Cargo.toml`
1717
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
1818

19-
error[E0670]: `async fn` is not permitted in the 2015 edition
19+
error[E0670]: `async fn` is not permitted in Rust 2015
2020
--> $DIR/edition-deny-async-fns-2015.rs:7:1
2121
|
2222
LL | async fn async_baz() {
23-
| ^^^^^ to use `async fn`, switch to Rust 2018
23+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
2424
|
2525
= help: set `edition = "2018"` in `Cargo.toml`
2626
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
2727

28-
error[E0670]: `async fn` is not permitted in the 2015 edition
28+
error[E0670]: `async fn` is not permitted in Rust 2015
2929
--> $DIR/edition-deny-async-fns-2015.rs:8:5
3030
|
3131
LL | async fn bar() {}
32-
| ^^^^^ to use `async fn`, switch to Rust 2018
32+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
3333
|
3434
= help: set `edition = "2018"` in `Cargo.toml`
3535
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
3636

37-
error[E0670]: `async fn` is not permitted in the 2015 edition
37+
error[E0670]: `async fn` is not permitted in Rust 2015
3838
--> $DIR/edition-deny-async-fns-2015.rs:14:5
3939
|
4040
LL | async fn foo() {}
41-
| ^^^^^ to use `async fn`, switch to Rust 2018
41+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
4242
|
4343
= help: set `edition = "2018"` in `Cargo.toml`
4444
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
4545

46-
error[E0670]: `async fn` is not permitted in the 2015 edition
46+
error[E0670]: `async fn` is not permitted in Rust 2015
4747
--> $DIR/edition-deny-async-fns-2015.rs:18:5
4848
|
4949
LL | async fn foo() {}
50-
| ^^^^^ to use `async fn`, switch to Rust 2018
50+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
5151
|
5252
= help: set `edition = "2018"` in `Cargo.toml`
5353
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
5454

55-
error[E0670]: `async fn` is not permitted in the 2015 edition
55+
error[E0670]: `async fn` is not permitted in Rust 2015
5656
--> $DIR/edition-deny-async-fns-2015.rs:36:9
5757
|
5858
LL | async fn bar() {}
59-
| ^^^^^ to use `async fn`, switch to Rust 2018
59+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
6060
|
6161
= help: set `edition = "2018"` in `Cargo.toml`
6262
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
6363

64-
error[E0670]: `async fn` is not permitted in the 2015 edition
64+
error[E0670]: `async fn` is not permitted in Rust 2015
6565
--> $DIR/edition-deny-async-fns-2015.rs:26:9
6666
|
6767
LL | async fn foo() {}
68-
| ^^^^^ to use `async fn`, switch to Rust 2018
68+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
6969
|
7070
= help: set `edition = "2018"` in `Cargo.toml`
7171
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
7272

73-
error[E0670]: `async fn` is not permitted in the 2015 edition
73+
error[E0670]: `async fn` is not permitted in Rust 2015
7474
--> $DIR/edition-deny-async-fns-2015.rs:31:13
7575
|
7676
LL | async fn bar() {}
77-
| ^^^^^ to use `async fn`, switch to Rust 2018
77+
| ^^^^^ to use `async fn`, switch to Rust 2018 or later
7878
|
7979
= help: set `edition = "2018"` in `Cargo.toml`
8080
= note: for more on editions, read https://doc.rust-lang.org/edition-guide

src/test/ui/async-await/suggest-switching-edition-on-await.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0609]: no field `await` on type `await_on_struct_missing::S`
44
LL | x.await;
55
| ^^^^^ unknown field
66
|
7-
= note: to `.await` a `Future`, switch to Rust 2018
7+
= note: to `.await` a `Future`, switch to Rust 2018 or later
88
= help: set `edition = "2018"` in `Cargo.toml`
99
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
1010

@@ -14,7 +14,7 @@ error[E0609]: no field `await` on type `await_on_struct_similar::S`
1414
LL | x.await;
1515
| ^^^^^ help: a field with a similar name exists: `awai`
1616
|
17-
= note: to `.await` a `Future`, switch to Rust 2018
17+
= note: to `.await` a `Future`, switch to Rust 2018 or later
1818
= help: set `edition = "2018"` in `Cargo.toml`
1919
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
2020

@@ -24,7 +24,7 @@ error[E0609]: no field `await` on type `Pin<&mut dyn Future<Output = ()>>`
2424
LL | x.await;
2525
| ^^^^^ unknown field
2626
|
27-
= note: to `.await` a `Future`, switch to Rust 2018
27+
= note: to `.await` a `Future`, switch to Rust 2018 or later
2828
= help: set `edition = "2018"` in `Cargo.toml`
2929
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
3030

@@ -34,7 +34,7 @@ error[E0609]: no field `await` on type `impl Future<Output = ()>`
3434
LL | x.await;
3535
| ^^^^^
3636
|
37-
= note: to `.await` a `Future`, switch to Rust 2018
37+
= note: to `.await` a `Future`, switch to Rust 2018 or later
3838
= help: set `edition = "2018"` in `Cargo.toml`
3939
= note: for more on editions, read https://doc.rust-lang.org/edition-guide
4040

0 commit comments

Comments
 (0)