Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add edition 2021. #79576

Merged
merged 4 commits into from
Jan 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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