about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2021-05-16 02:04:58 +0200
committerJonas Schievink <jonasschievink@gmail.com>2021-05-16 02:06:40 +0200
commitbd16825767d53dad8851e0e36c0d2c2392b1384c (patch)
tree09e584b79d8488a87235ee55b4449b52ac7c18c9
parent8cf990c9b5c59f25c806fad9f4466f9d6509bbea (diff)
downloadrust-bd16825767d53dad8851e0e36c0d2c2392b1384c.tar.gz
rust-bd16825767d53dad8851e0e36c0d2c2392b1384c.zip
Allow `async {}` expressions in const contexts
-rw-r--r--compiler/rustc_feature/src/active.rs3
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/ops.rs12
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--src/test/ui/consts/async-block.rs17
-rw-r--r--src/test/ui/consts/async-block.stderr8
-rw-r--r--src/test/ui/consts/async-block.with_feature.stderr8
-rw-r--r--src/test/ui/consts/async-block.without_feature.stderr19
-rw-r--r--src/test/ui/impl-trait/issues/issue-78721.stderr7
-rw-r--r--src/test/ui/impl-trait/issues/issue-78722.full_tait.stderr7
-rw-r--r--src/test/ui/impl-trait/issues/issue-78722.min_tait.stderr7
10 files changed, 70 insertions, 19 deletions
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 <https://github.com/rust-lang/rust/issues/77361>
+// 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 <https://github.com/rust-lang/rust/issues/77361>
 const _: i32 = { core::mem::ManuallyDrop::new(async { 0 }); 4 };
-//~^ `async` block
+//[without_feature]~^ `async` block
+
+static _FUT: &(dyn Future<Output = ()> + Sync) = &async {};
+//[without_feature]~^ `async` block
 
-fn main() {}
+#[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<Output = ()> + 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 <https://github.com/rust-lang/rust/issues/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<Output = u8> = 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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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`.