Function std::intrinsics::const_eval_select

const: unstable · source ·
pub unsafe extern "rust-intrinsic" fn const_eval_select<ARG, F, G, RET>(
    arg: ARG,
    called_in_const: F,
    called_at_rt: G
) -> RETwhere
    ARG: Tuple,
    G: FnOnce<ARG, Output = RET>,
    F: FnOnce<ARG, Output = RET>,
🔬This is a nightly-only experimental API. (core_intrinsics)
Expand description

根据上下文选择要调用的函数。

如果在编译时对该函数求值,那么这个内部函数的调用将被替换为 called_in_const 的调用。 否则,它会被替换为对 called_at_rt 的调用。

类型要求

这两个函数必须都是函数项。它们不能是函数指针或闭包。第一个函数必须是 const fn

arg 将是元组参数,将传递给两个函数之一,因此,两个函数必须接受相同类型的参数。

两个函数都必须返回 RET。

Safety

这两个函数必须表现出可观察到的等价性。 其他 crates 中的安全代码可能假设在编译时和运行时调用 const fn 会产生相同的结果。 在运行时计算时会产生不同结果或具有任何其他可观察到的副作用的函数是 unsound

这是一个可能导致问题的示例:

#![feature(const_eval_select)]
#![feature(core_intrinsics)]
use std::hint::unreachable_unchecked;
use std::intrinsics::const_eval_select;

// Crate A
pub const fn inconsistent() -> i32 {
    fn runtime() -> i32 { 1 }
    const fn compiletime() -> i32 { 2 }

    unsafe {
        // 和 `runtime`。
        const_eval_select((), compiletime, runtime)
    }
}

// Crate B
const X: i32 = inconsistent();
let x = inconsistent();
if x != X { unsafe { unreachable_unchecked(); }}
Run

此代码在运行时会导致未定义行为,因为实际上已到达 unreachable_unchecked。 该错误在 crate A 中,这违反了 const fn 在编译时和运行时必须表现相同的原则。 crate B 中的不安全代码没问题。