Change:
As shown in const-qualification can ignore some s, in the context of libcore / rustc crates: This should not compile without "miri unleashed"; const-qualification does not see this function as const since the unstable feature is not enabled, and thus does not check it. It outside of libcore, nor . cc More discussion is also available . I have a fix and will post a PR shortly. There are a couple of existing cases in where this matters (for and ), and I'll fix those at the same time.

Discussion:
#![feature(const_fn)] #![feature(const_fn_union)] #![feature(const_generics)] <ins> #![cfg_attr(not(bootstrap), feature(const_ptr_offset_from))] #![cfg_attr(not(bootstrap), feature(const_type_name))] </ins> #![feature(custom_inner_attributes)] #![feature(decl_macro)] #![feature(doc_cfg)]

let mode = match tcx.hir().body_owner_kind(hir_id) { HirKind::Closure => return None, <del> HirKind::Fn if tcx.is_const_fn(def_id) => ConstKind::ConstFn, </del> <ins> // Note: this is deliberately checking for `is_const_fn_raw`, as the `is_const_fn` // checks take into account the `rustc_const_unstable` attribute combined with enabled // feature gates. Otherwise, const qualification would _not check_ whether this // function body follows the `const fn` rules, as an unstable `const fn` would // be considered "not const". More details are available in issue #67053. HirKind::Fn if tcx.is_const_fn_raw(def_id) => ConstKind::ConstFn, </ins> HirKind::Fn => return None, HirKind::Const => ConstKind::Const,

<ins> // This is a non-regression test for const-qualification of unstable items in libcore // as explained in issue #67053. // const-qualification could miss some `const fn`s if they were unstable and the feature // gate was not enabled in libcore. #![stable(feature = "core", since = "1.6.0")] #![feature(const_if_match)] #![feature(rustc_const_unstable)] #![feature(staged_api)] enum Opt<T> { Some(T), None, } impl<T> Opt<T> { #[rustc_const_unstable(feature = "foo")] #[stable(feature = "rust1", since = "1.0.0")] const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T { //~^ ERROR destructors cannot be evaluated at compile-time //~| ERROR destructors cannot be evaluated at compile-time match self { Opt::Some(t) => t, Opt::None => f(), //~ ERROR E0015 } } } fn main() {} </ins>

<ins> error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants --> $DIR/unstable-const-fn-in-libcore.rs:24:26 | LL |             Opt::None => f(), |                          ^^^ error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/unstable-const-fn-in-libcore.rs:19:53 | LL |     const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T { |                                                     ^ constant functions cannot evaluate destructors error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/unstable-const-fn-in-libcore.rs:19:47 | LL |     const fn unwrap_or_else<F: FnOnce() -> T>(self, f: F) -> T { |                                               ^^^^ constant functions cannot evaluate destructors error: aborting due to 3 previous errors Some errors have detailed explanations: E0015, E0493. For more information about an error, try `rustc --explain E0015`. </ins>