diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2020-10-02 20:27:08 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-02 20:27:08 +0200 |
| commit | cac5352e334d96d36ee09dbefa765037b5f834e2 (patch) | |
| tree | 09235f7c9b0a23e51f13e09f3a92409743e22758 | |
| parent | 18ac26d1c5f60c9753a1d0ab8bb1499cf2669797 (diff) | |
| parent | b48def819e8ddf8c073f34459948ed8fc77d6e94 (diff) | |
| download | rust-cac5352e334d96d36ee09dbefa765037b5f834e2.tar.gz rust-cac5352e334d96d36ee09dbefa765037b5f834e2.zip | |
Rollup merge of #77415 - ecstatic-morse:const-checking-async-block, r=oli-obk
Better error message for `async` blocks in a const-context Improves the error message for the case in #77361. r? @oli-obk
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/ops.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/validation.rs | 10 | ||||
| -rw-r--r-- | src/test/ui/consts/async-block.rs | 8 | ||||
| -rw-r--r-- | src/test/ui/consts/async-block.stderr | 8 |
4 files changed, 28 insertions, 3 deletions
diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 25ed7859d21..32e233e337d 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -151,14 +151,15 @@ impl NonConstOp for FnPtrCast { } #[derive(Debug)] -pub struct Generator; +pub struct Generator(pub hir::GeneratorKind); impl NonConstOp for Generator { fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status { Status::Forbidden } fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> { - ccx.tcx.sess.struct_span_err(span, "Generators and `async` functions cannot be `const`") + let msg = format!("{}s are not allowed in {}s", self.0, ccx.const_kind()); + ccx.tcx.sess.struct_span_err(span, &msg) } } diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index ab63fd03a33..4e714bfeed3 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -770,6 +770,14 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { return; } + // `async` blocks get lowered to `std::future::from_generator(/* a closure */)`. + let is_async_block = Some(callee) == tcx.lang_items().from_generator_fn(); + if is_async_block { + let kind = hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block); + self.check_op(ops::Generator(kind)); + return; + } + // HACK: This is to "unstabilize" the `transmute` intrinsic // within const fns. `transmute` is allowed in all other const contexts. // This won't really scale to more intrinsics or functions. Let's allow const @@ -869,7 +877,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { TerminatorKind::Abort => self.check_op(ops::Abort), TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => { - self.check_op(ops::Generator) + self.check_op(ops::Generator(hir::GeneratorKind::Gen)) } TerminatorKind::Assert { .. } diff --git a/src/test/ui/consts/async-block.rs b/src/test/ui/consts/async-block.rs new file mode 100644 index 00000000000..1fa2a616091 --- /dev/null +++ b/src/test/ui/consts/async-block.rs @@ -0,0 +1,8 @@ +// From <https://github.com/rust-lang/rust/issues/77361> + +// edition:2018 + +const _: i32 = { core::mem::ManuallyDrop::new(async { 0 }); 4 }; +//~^ `async` block + +fn main() {} diff --git a/src/test/ui/consts/async-block.stderr b/src/test/ui/consts/async-block.stderr new file mode 100644 index 00000000000..99f470623ac --- /dev/null +++ b/src/test/ui/consts/async-block.stderr @@ -0,0 +1,8 @@ +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 + |
