about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Lueg <lukas.lueg@gmail.com>2022-05-06 09:34:41 +0200
committerLukas Lueg <lukas.lueg@gmail.com>2022-05-06 09:34:41 +0200
commitcd1746b2b4275a3437581992e2cb38f104b74b6c (patch)
treeef9968419391f0c7c4de91984a479807a7e87429
parent3615cb476b30d4058f397f45016e9b1823b4c870 (diff)
downloadrust-cd1746b2b4275a3437581992e2cb38f104b74b6c.tar.gz
rust-cd1746b2b4275a3437581992e2cb38f104b74b6c.zip
Clarify unreachable_unchecked docs
-rw-r--r--library/core/src/hint.rs25
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