1
Fork 0

adjust const_eval_select documentation

This commit is contained in:
Ralf Jung 2021-11-28 13:48:53 -05:00
parent e6d2de9483
commit 15a4ed6937

View file

@ -2271,19 +2271,40 @@ pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
/// ///
/// # Safety /// # Safety
/// ///
/// This intrinsic allows breaking [referential transparency] in `const fn` /// The two functions must behave observably equivalent. Safe code in other
/// and is therefore `unsafe`. /// crates may assume that calling a `const fn` at compile-time and at run-time
/// produces the same result. A function that produces a different result when
/// evaluated at run-time, or has any other observable side-effects, is
/// *unsound*.
/// ///
/// Code that uses this intrinsic must be extremely careful to ensure that /// Here is an example of how this could cause a problem:
/// `const fn`s remain referentially-transparent independently of when they /// ```no_run
/// are evaluated. /// #![feature(const_eval_select)]
/// use std::hint::unreachable_unchecked;
/// use std::intrinsics::const_eval_select;
/// ///
/// The Rust compiler assumes that it is sound to replace a call to a `const /// // Crate A
/// fn` with the result produced by evaluating it at compile-time. If /// pub const fn inconsistent() -> i32 {
/// evaluating the function at run-time were to produce a different result, /// fn runtime() -> i32 { 1 }
/// or have any other observable side-effects, the behavior is undefined. /// const fn compiletime() -> i32 { 2 }
/// ///
/// [referential transparency]: https://en.wikipedia.org/wiki/Referential_transparency /// unsafe {
// // ⚠ This code violates the required equivalence of `compiletime`
/// // and `runtime`.
/// const_eval_select((), compiletime, runtime)
/// }
/// }
///
/// // Crate B
/// const X: i32 = inconsistent();
/// let x = inconsistent();
/// if x != X { unsafe { unreachable_unchecked(); }}
/// ```
///
/// This code causes Undefined Behavior when being run, since the
/// `unreachable_unchecked` is actually being reached. The bug is in *crate A*,
/// which violates the principle that a `const fn` must behave the same at
/// compile-time and at run-time. The unsafe code in crate B is fine.
#[unstable( #[unstable(
feature = "const_eval_select", feature = "const_eval_select",
issue = "none", issue = "none",