adjust const_eval_select documentation
This commit is contained in:
parent
e6d2de9483
commit
15a4ed6937
1 changed files with 31 additions and 10 deletions
|
@ -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",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue