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 中的不安全代码没问题。