@@ -10,10 +10,11 @@ use crate::intrinsics;
10
10
///
11
11
/// # Safety
12
12
///
13
- /// Reaching this function is *Undefined Behavior* (UB). In particular, as the
14
- /// compiler assumes that all forms of Undefined Behavior can never happen, it
15
- /// will eliminate all branches which themselves reach a call to
16
- /// `unreachable_unchecked()`.
13
+ /// Reaching this function is *Undefined Behavior*.
14
+ ///
15
+ /// As the compiler assumes that all forms of Undefined Behavior can never
16
+ /// happen, it will eliminate all branches in the surrounding code that it can
17
+ /// determine will invariably lead to a call to `unreachable_unchecked()`.
17
18
///
18
19
/// If the assumptions embedded in using this function turn out to be wrong -
19
20
/// that is, if the site which is calling `unreachable_unchecked()` is actually
@@ -40,15 +41,17 @@ use crate::intrinsics;
40
41
/// divisors.retain(|divisor| *divisor != 0)
41
42
/// }
42
43
///
43
- /// fn do_computation(i: u32, divisors: &[u32]) -> u32 {
44
+ /// /// # Safety
45
+ /// /// All elements of `divisor` must be non-zero.
46
+ /// unsafe fn do_computation(i: u32, divisors: &[u32]) -> u32 {
44
47
/// divisors.iter().fold(i, |acc, divisor| {
45
48
/// // Convince the compiler that a division by zero can't happen here
46
49
/// // and a check is not needed below.
47
50
/// if *divisor == 0 {
48
- /// // SAFETY : `divisor` can't be zero because of `prepare_inputs`,
51
+ /// // Safety : `divisor` can't be zero because of `prepare_inputs`,
49
52
/// // but the compiler does not know about this. We *promise*
50
53
/// // that we always call `prepare_inputs`.
51
- /// unsafe { std::hint::unreachable_unchecked() }
54
+ /// std::hint::unreachable_unchecked()
52
55
/// }
53
56
/// // The compiler would normally introduce a check here that prevents
54
57
/// // a division by zero. However, if `divisor` was zero, the branch
@@ -61,11 +64,15 @@ use crate::intrinsics;
61
64
///
62
65
/// let mut divisors = vec![2, 0, 4];
63
66
/// prepare_inputs(&mut divisors);
64
- /// assert_eq!(do_computation(100, &divisors), 12);
67
+ /// let result = unsafe {
68
+ /// // Safety: prepare_inputs() guarantees that divisors is non-zero
69
+ /// do_computation(100, &divisors)
70
+ /// };
71
+ /// assert_eq!(result, 12);
65
72
///
66
73
/// ```
67
74
///
68
- /// While using `unreachable_unchecked()` is perfectly safe in the following
75
+ /// While using `unreachable_unchecked()` is perfectly sound in the following
69
76
/// example, the compiler is able to prove that a division by zero is not
70
77
/// possible. Benchmarking reveals that `unreachable_unchecked()` provides
71
78
/// no benefit over using [`unreachable!`], while the latter does not introduce
0 commit comments