diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index ee6adbc7a45..bee6aa60360 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -1,8 +1,8 @@ //! The `Visitor` responsible for actually checking a `mir::Body` for invalid operations. use rustc_errors::struct_span_err; -use rustc_hir::{self as hir, LangItem}; -use rustc_hir::{def_id::DefId, HirId}; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::{self as hir, HirId, LangItem}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -204,6 +204,13 @@ impl Validator<'mir, 'tcx> { pub fn check_body(&mut self) { let ConstCx { tcx, body, def_id, .. } = *self.ccx; + // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's + // no need to emit duplicate errors here. + if is_async_fn(tcx, def_id) || body.generator_kind.is_some() { + tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`"); + return; + } + // The local type and predicate checks are not free and only relevant for `const fn`s. if self.const_kind() == hir::ConstContext::ConstFn { // Prevent const trait methods from being annotated as `stable`. @@ -877,3 +884,11 @@ fn place_as_reborrow( fn is_int_bool_or_char(ty: Ty<'_>) -> bool { ty.is_bool() || ty.is_integral() || ty.is_char() } + +fn is_async_fn(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { + let hir_map = tcx.hir(); + let hir_id = hir_map.local_def_id_to_hir_id(def_id); + hir_map + .fn_sig_by_hir_id(hir_id) + .map_or(false, |sig| sig.header.asyncness == hir::IsAsync::Async) +} diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs index 57a9f175ca3..b3c59734e03 100644 --- a/src/test/ui/async-await/no-const-async.rs +++ b/src/test/ui/async-await/no-const-async.rs @@ -3,4 +3,3 @@ pub const async fn x() {} //~^ ERROR functions cannot be both `const` and `async` -//~| ERROR `impl Trait` in const fn is unstable diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index 4e59bb50767..90ec646c8c0 100644 --- a/src/test/ui/async-await/no-const-async.stderr +++ b/src/test/ui/async-await/no-const-async.stderr @@ -7,15 +7,5 @@ LL | pub const async fn x() {} | | `async` because of this | `const` because of this -error[E0723]: `impl Trait` in const fn is unstable - --> $DIR/no-const-async.rs:4:24 - | -LL | pub const async fn x() {} - | ^ - | - = note: see issue #57563 for more information - = help: add `#![feature(const_fn)]` to the crate attributes to enable +error: aborting due to previous error -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0723`. diff --git a/src/test/ui/parser/fn-header-semantic-fail.rs b/src/test/ui/parser/fn-header-semantic-fail.rs index 6d3fc3ce2f1..c327667f4cd 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.rs +++ b/src/test/ui/parser/fn-header-semantic-fail.rs @@ -12,7 +12,6 @@ fn main() { extern "C" fn ff4() {} // OK. const async unsafe extern "C" fn ff5() {} // OK. //~^ ERROR functions cannot be both `const` and `async` - //~| ERROR `from_generator` is not yet stable as a const fn trait X { async fn ft1(); //~ ERROR functions in traits cannot be declared `async` @@ -35,7 +34,6 @@ fn main() { const async unsafe extern "C" fn ft5() {} //~^ ERROR functions in traits cannot be declared `async` //~| ERROR functions in traits cannot be declared const - //~| ERROR `from_generator` is not yet stable as a const fn //~| ERROR method `ft5` has an incompatible type for trait //~| ERROR functions cannot be both `const` and `async` } @@ -47,7 +45,6 @@ fn main() { extern "C" fn fi4() {} // OK. const async unsafe extern "C" fn fi5() {} //~^ ERROR functions cannot be both `const` and `async` - //~| ERROR `from_generator` is not yet stable as a const fn } extern { diff --git a/src/test/ui/parser/fn-header-semantic-fail.stderr b/src/test/ui/parser/fn-header-semantic-fail.stderr index f1e21884040..4193b3ee695 100644 --- a/src/test/ui/parser/fn-header-semantic-fail.stderr +++ b/src/test/ui/parser/fn-header-semantic-fail.stderr @@ -8,7 +8,7 @@ LL | const async unsafe extern "C" fn ff5() {} // OK. | `const` because of this error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:18:9 + --> $DIR/fn-header-semantic-fail.rs:17:9 | LL | async fn ft1(); | -----^^^^^^^^^^ @@ -19,19 +19,19 @@ LL | async fn ft1(); = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait error[E0379]: functions in traits cannot be declared const - --> $DIR/fn-header-semantic-fail.rs:20:9 + --> $DIR/fn-header-semantic-fail.rs:19:9 | LL | const fn ft3(); | ^^^^^ functions in traits cannot be const error[E0379]: functions in traits cannot be declared const - --> $DIR/fn-header-semantic-fail.rs:22:9 + --> $DIR/fn-header-semantic-fail.rs:21:9 | LL | const async unsafe extern "C" fn ft5(); | ^^^^^ functions in traits cannot be const error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:22:9 + --> $DIR/fn-header-semantic-fail.rs:21:9 | LL | const async unsafe extern "C" fn ft5(); | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | const async unsafe extern "C" fn ft5(); = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:22:9 + --> $DIR/fn-header-semantic-fail.rs:21:9 | LL | const async unsafe extern "C" fn ft5(); | ^^^^^-^^^^^---------------------------- @@ -51,7 +51,7 @@ LL | const async unsafe extern "C" fn ft5(); | `const` because of this error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:30:9 + --> $DIR/fn-header-semantic-fail.rs:29:9 | LL | async fn ft1() {} | -----^^^^^^^^^^^^ @@ -62,19 +62,19 @@ LL | async fn ft1() {} = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait error[E0379]: functions in traits cannot be declared const - --> $DIR/fn-header-semantic-fail.rs:33:9 + --> $DIR/fn-header-semantic-fail.rs:32:9 | LL | const fn ft3() {} | ^^^^^ functions in traits cannot be const error[E0379]: functions in traits cannot be declared const - --> $DIR/fn-header-semantic-fail.rs:35:9 + --> $DIR/fn-header-semantic-fail.rs:34:9 | LL | const async unsafe extern "C" fn ft5() {} | ^^^^^ functions in traits cannot be const error[E0706]: functions in traits cannot be declared `async` - --> $DIR/fn-header-semantic-fail.rs:35:9 + --> $DIR/fn-header-semantic-fail.rs:34:9 | LL | const async unsafe extern "C" fn ft5() {} | ^^^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -85,7 +85,7 @@ LL | const async unsafe extern "C" fn ft5() {} = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:35:9 + --> $DIR/fn-header-semantic-fail.rs:34:9 | LL | const async unsafe extern "C" fn ft5() {} | ^^^^^-^^^^^------------------------------ @@ -94,7 +94,7 @@ LL | const async unsafe extern "C" fn ft5() {} | `const` because of this error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:48:9 + --> $DIR/fn-header-semantic-fail.rs:46:9 | LL | const async unsafe extern "C" fn fi5() {} | ^^^^^-^^^^^------------------------------ @@ -103,7 +103,7 @@ LL | const async unsafe extern "C" fn fi5() {} | `const` because of this error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:54:18 + --> $DIR/fn-header-semantic-fail.rs:51:18 | LL | extern { | ------ in this `extern` block @@ -113,7 +113,7 @@ LL | async fn fe1(); | help: remove the qualifiers: `fn` error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:55:19 + --> $DIR/fn-header-semantic-fail.rs:52:19 | LL | extern { | ------ in this `extern` block @@ -124,7 +124,7 @@ LL | unsafe fn fe2(); | help: remove the qualifiers: `fn` error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:56:18 + --> $DIR/fn-header-semantic-fail.rs:53:18 | LL | extern { | ------ in this `extern` block @@ -135,7 +135,7 @@ LL | const fn fe3(); | help: remove the qualifiers: `fn` error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:57:23 + --> $DIR/fn-header-semantic-fail.rs:54:23 | LL | extern { | ------ in this `extern` block @@ -146,7 +146,7 @@ LL | extern "C" fn fe4(); | help: remove the qualifiers: `fn` error: functions in `extern` blocks cannot have qualifiers - --> $DIR/fn-header-semantic-fail.rs:58:42 + --> $DIR/fn-header-semantic-fail.rs:55:42 | LL | extern { | ------ in this `extern` block @@ -157,7 +157,7 @@ LL | const async unsafe extern "C" fn fe5(); | help: remove the qualifiers: `fn` error: functions cannot be both `const` and `async` - --> $DIR/fn-header-semantic-fail.rs:58:9 + --> $DIR/fn-header-semantic-fail.rs:55:9 | LL | const async unsafe extern "C" fn fe5(); | ^^^^^-^^^^^---------------------------- @@ -165,16 +165,8 @@ LL | const async unsafe extern "C" fn fe5(); | | `async` because of this | `const` because of this -error: `from_generator` is not yet stable as a const fn - --> $DIR/fn-header-semantic-fail.rs:13:44 - | -LL | const async unsafe extern "C" fn ff5() {} // OK. - | ^^ - | - = help: add `#![feature(gen_future)]` to the crate attributes to enable - error[E0053]: method `ft1` has an incompatible type for trait - --> $DIR/fn-header-semantic-fail.rs:30:24 + --> $DIR/fn-header-semantic-fail.rs:29:24 | LL | async fn ft1(); | - type in trait @@ -189,7 +181,7 @@ LL | async fn ft1() {} found fn pointer `fn() -> impl Future` error[E0053]: method `ft5` has an incompatible type for trait - --> $DIR/fn-header-semantic-fail.rs:35:48 + --> $DIR/fn-header-semantic-fail.rs:34:48 | LL | const async unsafe extern "C" fn ft5(); | - type in trait @@ -203,23 +195,7 @@ LL | const async unsafe extern "C" fn ft5() {} = note: expected fn pointer `unsafe extern "C" fn()` found fn pointer `unsafe extern "C" fn() -> impl Future` -error: `from_generator` is not yet stable as a const fn - --> $DIR/fn-header-semantic-fail.rs:35:48 - | -LL | const async unsafe extern "C" fn ft5() {} - | ^^ - | - = help: add `#![feature(gen_future)]` to the crate attributes to enable - -error: `from_generator` is not yet stable as a const fn - --> $DIR/fn-header-semantic-fail.rs:48:48 - | -LL | const async unsafe extern "C" fn fi5() {} - | ^^ - | - = help: add `#![feature(gen_future)]` to the crate attributes to enable - -error: aborting due to 23 previous errors +error: aborting due to 20 previous errors Some errors have detailed explanations: E0053, E0379, E0706. For more information about an error, try `rustc --explain E0053`.