diff options
| author | Lukas Lueg <lukas.lueg@gmail.com> | 2022-05-06 09:34:41 +0200 |
|---|---|---|
| committer | Lukas Lueg <lukas.lueg@gmail.com> | 2022-05-06 09:34:41 +0200 |
| commit | cd1746b2b4275a3437581992e2cb38f104b74b6c (patch) | |
| tree | ef9968419391f0c7c4de91984a479807a7e87429 | |
| parent | 3615cb476b30d4058f397f45016e9b1823b4c870 (diff) | |
| download | rust-cd1746b2b4275a3437581992e2cb38f104b74b6c.tar.gz rust-cd1746b2b4275a3437581992e2cb38f104b74b6c.zip | |
Clarify unreachable_unchecked docs
| -rw-r--r-- | library/core/src/hint.rs | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 2473fbd1866..7ae1bfd4f35 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -10,10 +10,11 @@ use crate::intrinsics; /// /// # Safety /// -/// Reaching this function is *Undefined Behavior* (UB). In particular, as the -/// compiler assumes that all forms of Undefined Behavior can never happen, it -/// will eliminate all branches which themselves reach a call to -/// `unreachable_unchecked()`. +/// Reaching this function is *Undefined Behavior*. +/// +/// As the compiler assumes that all forms of Undefined Behavior can never +/// happen, it will eliminate all branches in the surrounding code that it can +/// determine will invariably lead to a call to `unreachable_unchecked()`. /// /// If the assumptions embedded in using this function turn out to be wrong - /// that is, if the site which is calling `unreachable_unchecked()` is actually @@ -40,15 +41,17 @@ use crate::intrinsics; /// divisors.retain(|divisor| *divisor != 0) /// } /// -/// fn do_computation(i: u32, divisors: &[u32]) -> u32 { +/// /// # Safety +/// /// All elements of `divisor` must be non-zero. +/// unsafe fn do_computation(i: u32, divisors: &[u32]) -> u32 { /// divisors.iter().fold(i, |acc, divisor| { /// // Convince the compiler that a division by zero can't happen here /// // and a check is not needed below. /// if *divisor == 0 { -/// // SAFETY: `divisor` can't be zero because of `prepare_inputs`, +/// // Safety: `divisor` can't be zero because of `prepare_inputs`, /// // but the compiler does not know about this. We *promise* /// // that we always call `prepare_inputs`. -/// unsafe { std::hint::unreachable_unchecked() } +/// std::hint::unreachable_unchecked() /// } /// // The compiler would normally introduce a check here that prevents /// // a division by zero. However, if `divisor` was zero, the branch @@ -61,11 +64,15 @@ use crate::intrinsics; /// /// let mut divisors = vec![2, 0, 4]; /// prepare_inputs(&mut divisors); -/// assert_eq!(do_computation(100, &divisors), 12); +/// let result = unsafe { +/// // Safety: prepare_inputs() guarantees that divisors is non-zero +/// do_computation(100, &divisors) +/// }; +/// assert_eq!(result, 12); /// /// ``` /// -/// While using `unreachable_unchecked()` is perfectly safe in the following +/// While using `unreachable_unchecked()` is perfectly sound in the following /// example, the compiler is able to prove that a division by zero is not /// possible. Benchmarking reveals that `unreachable_unchecked()` provides /// no benefit over using [`unreachable!`], while the latter does not introduce |
