@@ -111,9 +111,8 @@ pub const unsafe fn unreachable_unchecked() -> ! {
111111
112112/// Makes a *soundness* promise to the compiler that `cond` holds.
113113///
114- /// This may allow the optimizer to simplify things,
115- /// but it might also make the generated code slower.
116- /// Either way, calling it will most likely make compilation take longer.
114+ /// This may allow the optimizer to simplify things, but it might also make the generated code
115+ /// slower. Either way, calling it will most likely make compilation take longer.
117116///
118117/// This is a situational tool for micro-optimization, and is allowed to do nothing.
119118/// Any use should come with a repeatable benchmark to show the value
@@ -130,9 +129,9 @@ pub const unsafe fn unreachable_unchecked() -> ! {
130129/// If ever you're tempted to write `assert_unchecked(false)`, then you're
131130/// actually looking for [`unreachable_unchecked()`].
132131///
133- /// You may know this from other places
134- /// as [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic)
135- /// or [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume).
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).
136135///
137136/// This promotes a correctness requirement to a soundness requirement.
138137/// Don't do that without very good reason.
@@ -141,6 +140,54 @@ pub const unsafe fn unreachable_unchecked() -> ! {
141140///
142141/// `cond` must be `true`. It's immediate UB to call this with `false`.
143142///
143+ /// # Example
144+ ///
145+ /// ```
146+ /// use core::hint;
147+ ///
148+ /// /// # Safety
149+ /// ///
150+ /// /// `p` must be nonnull and valid
151+ /// pub unsafe fn next_value(p: *const i32) -> i32 {
152+ /// // SAFETY: caller invariants guarantee that `p` is not null
153+ /// unsafe { hint::assert_unchecked(!p.is_null()) }
154+ ///
155+ /// if p.is_null() {
156+ /// return -1;
157+ /// } else {
158+ /// // SAFETY: caller invariants guarantee that `p` is valid
159+ /// unsafe { *p + 1 }
160+ /// }
161+ /// }
162+ /// ```
163+ ///
164+ /// Without the `assert_unchecked`, the above function produces the following with optimizations:
165+ ///
166+ /// ```asm
167+ /// next_value:
168+ /// test rdi, rdi
169+ /// je .LBB0_1
170+ /// mov eax, dword ptr [rdi]
171+ /// inc eax
172+ /// ret
173+ /// .LBB0_1:
174+ /// mov eax, -1
175+ /// ret
176+ /// ```
177+ ///
178+ /// Adding the assertion allows the optimizer to remove the extra check:
179+ ///
180+ /// ```asm
181+ /// next_value:
182+ /// mov eax, dword ptr [rdi]
183+ /// inc eax
184+ /// ret
185+ /// ```
186+ ///
187+ /// This example is quite unlike anything that would happen in the real world: it is redundant to
188+ /// 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.
144191#[ inline( always) ]
145192#[ doc( alias = "assume" ) ]
146193#[ track_caller]
0 commit comments