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
This commit is contained in:
commit
cac5352e33
4 changed files with 28 additions and 3 deletions
|
@ -151,14 +151,15 @@ impl NonConstOp for FnPtrCast {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Generator;
|
pub struct Generator(pub hir::GeneratorKind);
|
||||||
impl NonConstOp for Generator {
|
impl NonConstOp for Generator {
|
||||||
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
|
fn status_in_item(&self, _: &ConstCx<'_, '_>) -> Status {
|
||||||
Status::Forbidden
|
Status::Forbidden
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -770,6 +770,14 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||||
return;
|
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
|
// HACK: This is to "unstabilize" the `transmute` intrinsic
|
||||||
// within const fns. `transmute` is allowed in all other const contexts.
|
// 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
|
// 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::Abort => self.check_op(ops::Abort),
|
||||||
|
|
||||||
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => {
|
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => {
|
||||||
self.check_op(ops::Generator)
|
self.check_op(ops::Generator(hir::GeneratorKind::Gen))
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminatorKind::Assert { .. }
|
TerminatorKind::Assert { .. }
|
||||||
|
|
8
src/test/ui/consts/async-block.rs
Normal file
8
src/test/ui/consts/async-block.rs
Normal file
|
@ -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() {}
|
8
src/test/ui/consts/async-block.stderr
Normal file
8
src/test/ui/consts/async-block.stderr
Normal file
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue