@@ -2271,19 +2271,40 @@ pub unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
22712271///
22722272/// # Safety
22732273///
2274- /// This intrinsic allows breaking [referential transparency] in `const fn`
2275- /// and is therefore `unsafe`.
2274+ /// The two functions must behave observably equivalent. Safe code in other
2275+ /// crates may assume that calling a `const fn` at compile-time and at run-time
2276+ /// produces the same result. A function that produces a different result when
2277+ /// evaluated at run-time, or has any other observable side-effects, is
2278+ /// *unsound*.
2279+ ///
2280+ /// Here is an example of how this could cause a problem:
2281+ /// ```no_run
2282+ /// #![feature(const_eval_select)]
2283+ /// use std::hint::unreachable_unchecked;
2284+ /// use std::intrinsics::const_eval_select;
2285+ ///
2286+ /// // Crate A
2287+ /// pub const fn inconsistent() -> i32 {
2288+ /// fn runtime() -> i32 { 1 }
2289+ /// const fn compiletime() -> i32 { 2 }
22762290///
2277- /// Code that uses this intrinsic must be extremely careful to ensure that
2278- /// `const fn`s remain referentially-transparent independently of when they
2279- /// are evaluated.
2291+ /// unsafe {
2292+ // // ⚠ This code violates the required equivalence of `compiletime`
2293+ /// // and `runtime`.
2294+ /// const_eval_select((), compiletime, runtime)
2295+ /// }
2296+ /// }
22802297///
2281- /// The Rust compiler assumes that it is sound to replace a call to a `const
2282- /// fn` with the result produced by evaluating it at compile-time. If
2283- /// evaluating the function at run-time were to produce a different result,
2284- /// or have any other observable side-effects, the behavior is undefined.
2298+ /// // Crate B
2299+ /// const X: i32 = inconsistent();
2300+ /// let x = inconsistent();
2301+ /// if x != X { unsafe { unreachable_unchecked(); }}
2302+ /// ```
22852303///
2286- /// [referential transparency]: https://en.wikipedia.org/wiki/Referential_transparency
2304+ /// This code causes Undefined Behavior when being run, since the
2305+ /// `unreachable_unchecked` is actually being reached. The bug is in *crate A*,
2306+ /// which violates the principle that a `const fn` must behave the same at
2307+ /// compile-time and at run-time. The unsafe code in crate B is fine.
22872308#[ unstable(
22882309 feature = "const_eval_select" ,
22892310 issue = "none" ,
0 commit comments