diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 9d96a9baa50..78ead47d1ba 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -650,6 +650,9 @@ declare_features! ( /// Allows unsizing coercions in `const fn`. (active, const_fn_unsize, "1.53.0", Some(64992), None), + /// Allows `async {}` expressions in const contexts. + (active, const_async_blocks, "1.53.0", None, None), + /// Allows using imported `main` function (active, imported_main, "1.53.0", Some(28937), None), diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index ffeaaf60a30..16f5f14f563 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -141,12 +141,20 @@ impl NonConstOp for FnPtrCast { pub struct Generator(pub hir::GeneratorKind); impl NonConstOp for Generator { fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status { - Status::Forbidden + if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 { + Status::Unstable(sym::const_async_blocks) + } else { + Status::Forbidden + } } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind()); - ccx.tcx.sess.struct_span_err(span, &msg) + if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 { + feature_err(&ccx.tcx.sess.parse_sess, sym::const_async_blocks, span, &msg) + } else { + ccx.tcx.sess.struct_span_err(span, &msg) + } } } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index c9816c2d599..502d4cd3272 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -374,6 +374,7 @@ symbols! { conservative_impl_trait, console, const_allocate, + const_async_blocks, const_compare_raw_pointers, const_constructor, const_eval_limit, diff --git a/src/test/ui/consts/async-block.rs b/src/test/ui/consts/async-block.rs index 1fa2a616091..78ec8aea724 100644 --- a/src/test/ui/consts/async-block.rs +++ b/src/test/ui/consts/async-block.rs @@ -1,8 +1,19 @@ -// From +// gate-test-const_async_blocks // edition:2018 +// revisions: with_feature without_feature +#![feature(rustc_attrs)] +#![cfg_attr(with_feature, feature(const_async_blocks))] + +use std::future::Future; + +// From const _: i32 = { core::mem::ManuallyDrop::new(async { 0 }); 4 }; -//~^ `async` block +//[without_feature]~^ `async` block -fn main() {} +static _FUT: &(dyn Future + Sync) = &async {}; +//[without_feature]~^ `async` block + +#[rustc_error] +fn main() {} //[with_feature]~ fatal error triggered by #[rustc_error] diff --git a/src/test/ui/consts/async-block.stderr b/src/test/ui/consts/async-block.stderr deleted file mode 100644 index 99f470623ac..00000000000 --- a/src/test/ui/consts/async-block.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error: `async` blocks are not allowed in constants - --> $DIR/async-block.rs:5:47 - | -LL | const _: i32 = { core::mem::ManuallyDrop::new(async { 0 }); 4 }; - | ^^^^^^^^^^^ - -error: aborting due to previous error - diff --git a/src/test/ui/consts/async-block.with_feature.stderr b/src/test/ui/consts/async-block.with_feature.stderr new file mode 100644 index 00000000000..8c6364aeca6 --- /dev/null +++ b/src/test/ui/consts/async-block.with_feature.stderr @@ -0,0 +1,8 @@ +error: fatal error triggered by #[rustc_error] + --> $DIR/async-block.rs:19:1 + | +LL | fn main() {} + | ^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/consts/async-block.without_feature.stderr b/src/test/ui/consts/async-block.without_feature.stderr new file mode 100644 index 00000000000..93d0fbd3950 --- /dev/null +++ b/src/test/ui/consts/async-block.without_feature.stderr @@ -0,0 +1,19 @@ +error[E0658]: `async` blocks are not allowed in constants + --> $DIR/async-block.rs:12:47 + | +LL | const _: i32 = { core::mem::ManuallyDrop::new(async { 0 }); 4 }; + | ^^^^^^^^^^^ + | + = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable + +error[E0658]: `async` blocks are not allowed in statics + --> $DIR/async-block.rs:15:51 + | +LL | static _FUT: &(dyn Future + Sync) = &async {}; + | ^^^^^^^^ + | + = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/impl-trait/issues/issue-78721.stderr b/src/test/ui/impl-trait/issues/issue-78721.stderr index 353e882b1af..b6acdfa048f 100644 --- a/src/test/ui/impl-trait/issues/issue-78721.stderr +++ b/src/test/ui/impl-trait/issues/issue-78721.stderr @@ -7,11 +7,13 @@ LL | #![feature(impl_trait_in_bindings)] = note: `#[warn(incomplete_features)]` on by default = note: see issue #63065 for more information -error: `async` blocks are not allowed in constants +error[E0658]: `async` blocks are not allowed in constants --> $DIR/issue-78721.rs:8:57 | LL | let f: impl core::future::Future = async { 1 }; | ^^^^^^^^^^^ + | + = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/issue-78721.rs:8:13 @@ -24,4 +26,5 @@ LL | }], error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0493, E0658. +For more information about an error, try `rustc --explain E0493`. diff --git a/src/test/ui/impl-trait/issues/issue-78722.full_tait.stderr b/src/test/ui/impl-trait/issues/issue-78722.full_tait.stderr index d7327aa46bc..f013547782e 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.full_tait.stderr +++ b/src/test/ui/impl-trait/issues/issue-78722.full_tait.stderr @@ -15,11 +15,13 @@ LL | #![feature(impl_trait_in_bindings)] | = note: see issue #63065 for more information -error: `async` blocks are not allowed in constants +error[E0658]: `async` blocks are not allowed in constants --> $DIR/issue-78722.rs:17:20 | LL | let f: F = async { 1 }; | ^^^^^^^^^^^ + | + = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/issue-78722.rs:17:13 @@ -32,4 +34,5 @@ LL | }], error: aborting due to 2 previous errors; 2 warnings emitted -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0493, E0658. +For more information about an error, try `rustc --explain E0493`. diff --git a/src/test/ui/impl-trait/issues/issue-78722.min_tait.stderr b/src/test/ui/impl-trait/issues/issue-78722.min_tait.stderr index 01ec71e7a50..9425bc48d69 100644 --- a/src/test/ui/impl-trait/issues/issue-78722.min_tait.stderr +++ b/src/test/ui/impl-trait/issues/issue-78722.min_tait.stderr @@ -7,11 +7,13 @@ LL | #![feature(impl_trait_in_bindings)] = note: `#[warn(incomplete_features)]` on by default = note: see issue #63065 for more information -error: `async` blocks are not allowed in constants +error[E0658]: `async` blocks are not allowed in constants --> $DIR/issue-78722.rs:17:20 | LL | let f: F = async { 1 }; | ^^^^^^^^^^^ + | + = help: add `#![feature(const_async_blocks)]` to the crate attributes to enable error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/issue-78722.rs:17:13 @@ -24,4 +26,5 @@ LL | }], error: aborting due to 2 previous errors; 1 warning emitted -For more information about this error, try `rustc --explain E0493`. +Some errors have detailed explanations: E0493, E0658. +For more information about an error, try `rustc --explain E0493`.