Skip to content

Commit 5ce23c1

Browse files
committed
Update documentation for hint::assert_unchecked
Rearrange the sections and add an example to `core::hint::assert_unchecked`.
1 parent 55e1775 commit 5ce23c1

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

library/core/src/hint.rs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -114,35 +114,41 @@ pub const unsafe fn unreachable_unchecked() -> ! {
114114
/// This may allow the optimizer to simplify things, but it might also make the generated code
115115
/// slower. Either way, calling it will most likely make compilation take longer.
116116
///
117-
/// This is a situational tool for micro-optimization, and is allowed to do nothing.
118-
/// Any use should come with a repeatable benchmark to show the value
119-
/// and allow removing it later should the optimizer get smarter and no longer need it.
117+
/// You may know this from other places as
118+
/// [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic) or, in C,
119+
/// [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume).
120120
///
121-
/// The more complicated the condition the less likely this is to be fruitful.
122-
/// For example, `assert_unchecked(foo.is_sorted())` is a complex enough value
123-
/// that the compiler is unlikely to be able to take advantage of it.
121+
/// This promotes a correctness requirement to a soundness requirement. Don't do that without
122+
/// very good reason.
124123
///
125-
/// There's also no need to `assert_unchecked` basic properties of things. For
126-
/// example, the compiler already knows the range of `count_ones`, so there's no
127-
/// benefit to `let n = u32::count_ones(x); assert_unchecked(n <= u32::BITS);`.
124+
/// # Usage
128125
///
129-
/// If ever you're tempted to write `assert_unchecked(false)`, then you're
130-
/// actually looking for [`unreachable_unchecked()`].
126+
/// This is a situational tool for micro-optimization, and is allowed to do nothing. Any use
127+
/// should come with a repeatable benchmark to show the value, with the expectation to drop it
128+
/// later should the optimizer get smarter and no longer need it.
131129
///
132-
/// You may know this from other places as
133-
/// [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic) or, in C,
134-
/// [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume).
130+
/// The more complicated the condition, the less likely this is to be fruitful. For example,
131+
/// `assert_unchecked(foo.is_sorted())` is a complex enough value that the compiler is unlikely
132+
/// to be able to take advantage of it.
133+
///
134+
/// There's also no need to `assert_unchecked` basic properties of things. For example, the
135+
/// compiler already knows the range of `count_ones`, so there is no benefit to
136+
/// `let n = u32::count_ones(x); assert_unchecked(n <= u32::BITS);`.
135137
///
136-
/// This promotes a correctness requirement to a soundness requirement.
137-
/// Don't do that without very good reason.
138+
/// In release mode, the argument will most likely not actually be evaluated.
139+
///
140+
/// If ever you are tempted to write `assert_unchecked(false)`, then you are actually looking for
141+
/// [`unreachable_unchecked()`].
138142
///
139143
/// # Safety
140144
///
141-
/// `cond` must be `true`. It's immediate UB to call this with `false`.
145+
/// `cond` must be `true`. It is immediate UB to call this with `false`.
142146
///
143147
/// # Example
144148
///
145149
/// ```
150+
/// #![feature(hint_assert_unchecked)]
151+
///
146152
/// use core::hint;
147153
///
148154
/// /// # Safety
@@ -161,7 +167,8 @@ pub const unsafe fn unreachable_unchecked() -> ! {
161167
/// }
162168
/// ```
163169
///
164-
/// Without the `assert_unchecked`, the above function produces the following with optimizations:
170+
/// Without the `assert_unchecked`, the above function produces the following with optimizations
171+
/// enabled:
165172
///
166173
/// ```asm
167174
/// next_value:
@@ -186,8 +193,9 @@ pub const unsafe fn unreachable_unchecked() -> ! {
186193
///
187194
/// This example is quite unlike anything that would happen in the real world: it is redundant to
188195
/// put an an assertion right next to code that checks the same thing, and dereferencing a
189-
/// pointer already has the builtin assumption that it is nonnull. The optimizer can make use of
190-
/// this information even when it isn't obvious, such as when checks happen in called functions.
196+
/// pointer already has the builtin assumption that it is nonnull. However, the optimizer can
197+
/// make use of this information even when it isn't as obvious, such as when checks happen in
198+
/// called functions.
191199
#[inline(always)]
192200
#[doc(alias = "assume")]
193201
#[track_caller]

0 commit comments

Comments
 (0)