core/
hint.rs

1#![stable(feature = "core_hint", since = "1.27.0")]
2
3//! Hints to compiler that affects how code should be emitted or optimized.
4//!
5//! Hints may be compile time or runtime.
6
7use crate::{intrinsics, ub_checks};
8
9/// Informs the compiler that the site which is calling this function is not
10/// reachable, possibly enabling further optimizations.
11///
12/// # Safety
13///
14/// Reaching this function is *Undefined Behavior*.
15///
16/// As the compiler assumes that all forms of Undefined Behavior can never
17/// happen, it will eliminate all branches in the surrounding code that it can
18/// determine will invariably lead to a call to `unreachable_unchecked()`.
19///
20/// If the assumptions embedded in using this function turn out to be wrong -
21/// that is, if the site which is calling `unreachable_unchecked()` is actually
22/// reachable at runtime - the compiler may have generated nonsensical machine
23/// instructions for this situation, including in seemingly unrelated code,
24/// causing difficult-to-debug problems.
25///
26/// Use this function sparingly. Consider using the [`unreachable!`] macro,
27/// which may prevent some optimizations but will safely panic in case it is
28/// actually reached at runtime. Benchmark your code to find out if using
29/// `unreachable_unchecked()` comes with a performance benefit.
30///
31/// # Examples
32///
33/// `unreachable_unchecked()` can be used in situations where the compiler
34/// can't prove invariants that were previously established. Such situations
35/// have a higher chance of occurring if those invariants are upheld by
36/// external code that the compiler can't analyze.
37/// ```
38/// fn prepare_inputs(divisors: &mut Vec<u32>) {
39///     // Note to future-self when making changes: The invariant established
40///     // here is NOT checked in `do_computation()`; if this changes, you HAVE
41///     // to change `do_computation()`.
42///     divisors.retain(|divisor| *divisor != 0)
43/// }
44///
45/// /// # Safety
46/// /// All elements of `divisor` must be non-zero.
47/// unsafe fn do_computation(i: u32, divisors: &[u32]) -> u32 {
48///     divisors.iter().fold(i, |acc, divisor| {
49///         // Convince the compiler that a division by zero can't happen here
50///         // and a check is not needed below.
51///         if *divisor == 0 {
52///             // Safety: `divisor` can't be zero because of `prepare_inputs`,
53///             // but the compiler does not know about this. We *promise*
54///             // that we always call `prepare_inputs`.
55///             std::hint::unreachable_unchecked()
56///         }
57///         // The compiler would normally introduce a check here that prevents
58///         // a division by zero. However, if `divisor` was zero, the branch
59///         // above would reach what we explicitly marked as unreachable.
60///         // The compiler concludes that `divisor` can't be zero at this point
61///         // and removes the - now proven useless - check.
62///         acc / divisor
63///     })
64/// }
65///
66/// let mut divisors = vec![2, 0, 4];
67/// prepare_inputs(&mut divisors);
68/// let result = unsafe {
69///     // Safety: prepare_inputs() guarantees that divisors is non-zero
70///     do_computation(100, &divisors)
71/// };
72/// assert_eq!(result, 12);
73///
74/// ```
75///
76/// While using `unreachable_unchecked()` is perfectly sound in the following
77/// example, as the compiler is able to prove that a division by zero is not
78/// possible, benchmarking reveals that `unreachable_unchecked()` provides
79/// no benefit over using [`unreachable!`], while the latter does not introduce
80/// the possibility of Undefined Behavior.
81///
82/// ```
83/// fn div_1(a: u32, b: u32) -> u32 {
84///     use std::hint::unreachable_unchecked;
85///
86///     // `b.saturating_add(1)` is always positive (not zero),
87///     // hence `checked_div` will never return `None`.
88///     // Therefore, the else branch is unreachable.
89///     a.checked_div(b.saturating_add(1))
90///         .unwrap_or_else(|| unsafe { unreachable_unchecked() })
91/// }
92///
93/// assert_eq!(div_1(7, 0), 7);
94/// assert_eq!(div_1(9, 1), 4);
95/// assert_eq!(div_1(11, u32::MAX), 0);
96/// ```
97#[inline]
98#[stable(feature = "unreachable", since = "1.27.0")]
99#[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")]
100#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
101pub const unsafe fn unreachable_unchecked() -> ! {
102    ub_checks::assert_unsafe_precondition!(
103        check_language_ub,
104        "hint::unreachable_unchecked must never be reached",
105        () => false
106    );
107    // SAFETY: the safety contract for `intrinsics::unreachable` must
108    // be upheld by the caller.
109    unsafe { intrinsics::unreachable() }
110}
111
112/// Makes a *soundness* promise to the compiler that `cond` holds.
113///
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.
116///
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).
120///
121/// This promotes a correctness requirement to a soundness requirement. Don't do that without
122/// very good reason.
123///
124/// # Usage
125///
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.
129///
130/// The more complicated the condition, the less likely this is to be useful. 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);`.
137///
138/// `assert_unchecked` is logically equivalent to `if !cond { unreachable_unchecked(); }`. If
139/// ever you are tempted to write `assert_unchecked(false)`, you should instead use
140/// [`unreachable_unchecked()`] directly.
141///
142/// # Safety
143///
144/// `cond` must be `true`. It is immediate UB to call this with `false`.
145///
146/// # Example
147///
148/// ```
149/// use core::hint;
150///
151/// /// # Safety
152/// ///
153/// /// `p` must be nonnull and valid
154/// pub unsafe fn next_value(p: *const i32) -> i32 {
155///     // SAFETY: caller invariants guarantee that `p` is not null
156///     unsafe { hint::assert_unchecked(!p.is_null()) }
157///
158///     if p.is_null() {
159///         return -1;
160///     } else {
161///         // SAFETY: caller invariants guarantee that `p` is valid
162///         unsafe { *p + 1 }
163///     }
164/// }
165/// ```
166///
167/// Without the `assert_unchecked`, the above function produces the following with optimizations
168/// enabled:
169///
170/// ```asm
171/// next_value:
172///         test    rdi, rdi
173///         je      .LBB0_1
174///         mov     eax, dword ptr [rdi]
175///         inc     eax
176///         ret
177/// .LBB0_1:
178///         mov     eax, -1
179///         ret
180/// ```
181///
182/// Adding the assertion allows the optimizer to remove the extra check:
183///
184/// ```asm
185/// next_value:
186///         mov     eax, dword ptr [rdi]
187///         inc     eax
188///         ret
189/// ```
190///
191/// This example is quite unlike anything that would be used in the real world: it is redundant
192/// to put an assertion right next to code that checks the same thing, and dereferencing a
193/// pointer already has the builtin assumption that it is nonnull. However, it illustrates the
194/// kind of changes the optimizer can make even when the behavior is less obviously related.
195#[track_caller]
196#[inline(always)]
197#[doc(alias = "assume")]
198#[stable(feature = "hint_assert_unchecked", since = "1.81.0")]
199#[rustc_const_stable(feature = "hint_assert_unchecked", since = "1.81.0")]
200pub const unsafe fn assert_unchecked(cond: bool) {
201    // SAFETY: The caller promised `cond` is true.
202    unsafe {
203        ub_checks::assert_unsafe_precondition!(
204            check_language_ub,
205            "hint::assert_unchecked must never be called when the condition is false",
206            (cond: bool = cond) => cond,
207        );
208        crate::intrinsics::assume(cond);
209    }
210}
211
212/// Emits a machine instruction to signal the processor that it is running in
213/// a busy-wait spin-loop ("spin lock").
214///
215/// Upon receiving the spin-loop signal the processor can optimize its behavior by,
216/// for example, saving power or switching hyper-threads.
217///
218/// This function is different from [`thread::yield_now`] which directly
219/// yields to the system's scheduler, whereas `spin_loop` does not interact
220/// with the operating system.
221///
222/// A common use case for `spin_loop` is implementing bounded optimistic
223/// spinning in a CAS loop in synchronization primitives. To avoid problems
224/// like priority inversion, it is strongly recommended that the spin loop is
225/// terminated after a finite amount of iterations and an appropriate blocking
226/// syscall is made.
227///
228/// **Note**: On platforms that do not support receiving spin-loop hints this
229/// function does not do anything at all.
230///
231/// # Examples
232///
233/// ```
234/// use std::sync::atomic::{AtomicBool, Ordering};
235/// use std::sync::Arc;
236/// use std::{hint, thread};
237///
238/// // A shared atomic value that threads will use to coordinate
239/// let live = Arc::new(AtomicBool::new(false));
240///
241/// // In a background thread we'll eventually set the value
242/// let bg_work = {
243///     let live = live.clone();
244///     thread::spawn(move || {
245///         // Do some work, then make the value live
246///         do_some_work();
247///         live.store(true, Ordering::Release);
248///     })
249/// };
250///
251/// // Back on our current thread, we wait for the value to be set
252/// while !live.load(Ordering::Acquire) {
253///     // The spin loop is a hint to the CPU that we're waiting, but probably
254///     // not for very long
255///     hint::spin_loop();
256/// }
257///
258/// // The value is now set
259/// # fn do_some_work() {}
260/// do_some_work();
261/// bg_work.join()?;
262/// # Ok::<(), Box<dyn core::any::Any + Send + 'static>>(())
263/// ```
264///
265/// [`thread::yield_now`]: ../../std/thread/fn.yield_now.html
266#[inline(always)]
267#[stable(feature = "renamed_spin_loop", since = "1.49.0")]
268pub fn spin_loop() {
269    #[cfg(target_arch = "x86")]
270    {
271        // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.
272        unsafe { crate::arch::x86::_mm_pause() };
273    }
274
275    #[cfg(target_arch = "x86_64")]
276    {
277        // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.
278        unsafe { crate::arch::x86_64::_mm_pause() };
279    }
280
281    #[cfg(target_arch = "riscv32")]
282    {
283        crate::arch::riscv32::pause();
284    }
285
286    #[cfg(target_arch = "riscv64")]
287    {
288        crate::arch::riscv64::pause();
289    }
290
291    #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
292    {
293        // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.
294        unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) };
295    }
296
297    #[cfg(all(target_arch = "arm", target_feature = "v6"))]
298    {
299        // SAFETY: the `cfg` attr ensures that we only execute this on arm targets
300        // with support for the v6 feature.
301        unsafe { crate::arch::arm::__yield() };
302    }
303}
304
305/// An identity function that *__hints__* to the compiler to be maximally pessimistic about what
306/// `black_box` could do.
307///
308/// Unlike [`std::convert::identity`], a Rust compiler is encouraged to assume that `black_box` can
309/// use `dummy` in any possible valid way that Rust code is allowed to without introducing undefined
310/// behavior in the calling code. This property makes `black_box` useful for writing code in which
311/// certain optimizations are not desired, such as benchmarks.
312///
313/// <div class="warning">
314///
315/// Note however, that `black_box` is only (and can only be) provided on a "best-effort" basis. The
316/// extent to which it can block optimisations may vary depending upon the platform and code-gen
317/// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the
318/// identity function. As such, it **must not be relied upon to control critical program behavior.**
319/// This also means that this function does not offer any guarantees for cryptographic or security
320/// purposes.
321///
322/// </div>
323///
324/// [`std::convert::identity`]: crate::convert::identity
325///
326/// # When is this useful?
327///
328/// While not suitable in those mission-critical cases, `black_box`'s functionality can generally be
329/// relied upon for benchmarking, and should be used there. It will try to ensure that the
330/// compiler doesn't optimize away part of the intended test code based on context. For
331/// example:
332///
333/// ```
334/// fn contains(haystack: &[&str], needle: &str) -> bool {
335///     haystack.iter().any(|x| x == &needle)
336/// }
337///
338/// pub fn benchmark() {
339///     let haystack = vec!["abc", "def", "ghi", "jkl", "mno"];
340///     let needle = "ghi";
341///     for _ in 0..10 {
342///         contains(&haystack, needle);
343///     }
344/// }
345/// ```
346///
347/// The compiler could theoretically make optimizations like the following:
348///
349/// - The `needle` and `haystack` do not change, move the call to `contains` outside the loop and
350///   delete the loop
351/// - Inline `contains`
352/// - `needle` and `haystack` have values known at compile time, `contains` is always true. Remove
353///   the call and replace with `true`
354/// - Nothing is done with the result of `contains`: delete this function call entirely
355/// - `benchmark` now has no purpose: delete this function
356///
357/// It is not likely that all of the above happens, but the compiler is definitely able to make some
358/// optimizations that could result in a very inaccurate benchmark. This is where `black_box` comes
359/// in:
360///
361/// ```
362/// use std::hint::black_box;
363///
364/// // Same `contains` function.
365/// fn contains(haystack: &[&str], needle: &str) -> bool {
366///     haystack.iter().any(|x| x == &needle)
367/// }
368///
369/// pub fn benchmark() {
370///     let haystack = vec!["abc", "def", "ghi", "jkl", "mno"];
371///     let needle = "ghi";
372///     for _ in 0..10 {
373///         // Force the compiler to run `contains`, even though it is a pure function whose
374///         // results are unused.
375///         black_box(contains(
376///             // Prevent the compiler from making assumptions about the input.
377///             black_box(&haystack),
378///             black_box(needle),
379///         ));
380///     }
381/// }
382/// ```
383///
384/// This essentially tells the compiler to block optimizations across any calls to `black_box`. So,
385/// it now:
386///
387/// - Treats both arguments to `contains` as unpredictable: the body of `contains` can no longer be
388///   optimized based on argument values
389/// - Treats the call to `contains` and its result as volatile: the body of `benchmark` cannot
390///   optimize this away
391///
392/// This makes our benchmark much more realistic to how the function would actually be used, where
393/// arguments are usually not known at compile time and the result is used in some way.
394///
395/// # How to use this
396///
397/// In practice, `black_box` serves two purposes:
398///
399/// 1. It prevents the compiler from making optimizations related to the value returned by `black_box`
400/// 2. It forces the value passed to `black_box` to be calculated, even if the return value of `black_box` is unused
401///
402/// ```
403/// use std::hint::black_box;
404///
405/// let zero = 0;
406/// let five = 5;
407///
408/// // The compiler will see this and remove the `* five` call, because it knows that multiplying
409/// // any integer by 0 will result in 0.
410/// let c = zero * five;
411///
412/// // Adding `black_box` here disables the compiler's ability to reason about the first operand in the multiplication.
413/// // It is forced to assume that it can be any possible number, so it cannot remove the `* five`
414/// // operation.
415/// let c = black_box(zero) * five;
416/// ```
417///
418/// While most cases will not be as clear-cut as the above example, it still illustrates how
419/// `black_box` can be used. When benchmarking a function, you usually want to wrap its inputs in
420/// `black_box` so the compiler cannot make optimizations that would be unrealistic in real-life
421/// use.
422///
423/// ```
424/// use std::hint::black_box;
425///
426/// // This is a simple function that increments its input by 1. Note that it is pure, meaning it
427/// // has no side-effects. This function has no effect if its result is unused. (An example of a
428/// // function *with* side-effects is `println!()`.)
429/// fn increment(x: u8) -> u8 {
430///     x + 1
431/// }
432///
433/// // Here, we call `increment` but discard its result. The compiler, seeing this and knowing that
434/// // `increment` is pure, will eliminate this function call entirely. This may not be desired,
435/// // though, especially if we're trying to track how much time `increment` takes to execute.
436/// let _ = increment(black_box(5));
437///
438/// // Here, we force `increment` to be executed. This is because the compiler treats `black_box`
439/// // as if it has side-effects, and thus must compute its input.
440/// let _ = black_box(increment(black_box(5)));
441/// ```
442///
443/// There may be additional situations where you want to wrap the result of a function in
444/// `black_box` to force its execution. This is situational though, and may not have any effect
445/// (such as when the function returns a zero-sized type such as [`()` unit][unit]).
446///
447/// Note that `black_box` has no effect on how its input is treated, only its output. As such,
448/// expressions passed to `black_box` may still be optimized:
449///
450/// ```
451/// use std::hint::black_box;
452///
453/// // The compiler sees this...
454/// let y = black_box(5 * 10);
455///
456/// // ...as this. As such, it will likely simplify `5 * 10` to just `50`.
457/// let _0 = 5 * 10;
458/// let y = black_box(_0);
459/// ```
460///
461/// In the above example, the `5 * 10` expression is considered distinct from the `black_box` call,
462/// and thus is still optimized by the compiler. You can prevent this by moving the multiplication
463/// operation outside of `black_box`:
464///
465/// ```
466/// use std::hint::black_box;
467///
468/// // No assumptions can be made about either operand, so the multiplication is not optimized out.
469/// let y = black_box(5) * black_box(10);
470/// ```
471///
472/// During constant evaluation, `black_box` is treated as a no-op.
473#[inline]
474#[stable(feature = "bench_black_box", since = "1.66.0")]
475#[rustc_const_stable(feature = "const_black_box", since = "1.86.0")]
476pub const fn black_box<T>(dummy: T) -> T {
477    crate::intrinsics::black_box(dummy)
478}
479
480/// An identity function that causes an `unused_must_use` warning to be
481/// triggered if the given value is not used (returned, stored in a variable,
482/// etc) by the caller.
483///
484/// This is primarily intended for use in macro-generated code, in which a
485/// [`#[must_use]` attribute][must_use] either on a type or a function would not
486/// be convenient.
487///
488/// [must_use]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute
489///
490/// # Example
491///
492/// ```
493/// #![feature(hint_must_use)]
494///
495/// use core::fmt;
496///
497/// pub struct Error(/* ... */);
498///
499/// #[macro_export]
500/// macro_rules! make_error {
501///     ($($args:expr),*) => {
502///         core::hint::must_use({
503///             let error = $crate::make_error(core::format_args!($($args),*));
504///             error
505///         })
506///     };
507/// }
508///
509/// // Implementation detail of make_error! macro.
510/// #[doc(hidden)]
511/// pub fn make_error(args: fmt::Arguments<'_>) -> Error {
512///     Error(/* ... */)
513/// }
514///
515/// fn demo() -> Option<Error> {
516///     if true {
517///         // Oops, meant to write `return Some(make_error!("..."));`
518///         Some(make_error!("..."));
519///     }
520///     None
521/// }
522/// #
523/// # // Make rustdoc not wrap the whole snippet in fn main, so that $crate::make_error works
524/// # fn main() {}
525/// ```
526///
527/// In the above example, we'd like an `unused_must_use` lint to apply to the
528/// value created by `make_error!`. However, neither `#[must_use]` on a struct
529/// nor `#[must_use]` on a function is appropriate here, so the macro expands
530/// using `core::hint::must_use` instead.
531///
532/// - We wouldn't want `#[must_use]` on the `struct Error` because that would
533///   make the following unproblematic code trigger a warning:
534///
535///   ```
536///   # struct Error;
537///   #
538///   fn f(arg: &str) -> Result<(), Error>
539///   # { Ok(()) }
540///
541///   #[test]
542///   fn t() {
543///       // Assert that `f` returns error if passed an empty string.
544///       // A value of type `Error` is unused here but that's not a problem.
545///       f("").unwrap_err();
546///   }
547///   ```
548///
549/// - Using `#[must_use]` on `fn make_error` can't help because the return value
550///   *is* used, as the right-hand side of a `let` statement. The `let`
551///   statement looks useless but is in fact necessary for ensuring that
552///   temporaries within the `format_args` expansion are not kept alive past the
553///   creation of the `Error`, as keeping them alive past that point can cause
554///   autotrait issues in async code:
555///
556///   ```
557///   # #![feature(hint_must_use)]
558///   #
559///   # struct Error;
560///   #
561///   # macro_rules! make_error {
562///   #     ($($args:expr),*) => {
563///   #         core::hint::must_use({
564///   #             // If `let` isn't used, then `f()` produces a non-Send future.
565///   #             let error = make_error(core::format_args!($($args),*));
566///   #             error
567///   #         })
568///   #     };
569///   # }
570///   #
571///   # fn make_error(args: core::fmt::Arguments<'_>) -> Error {
572///   #     Error
573///   # }
574///   #
575///   async fn f() {
576///       // Using `let` inside the make_error expansion causes temporaries like
577///       // `unsync()` to drop at the semicolon of that `let` statement, which
578///       // is prior to the await point. They would otherwise stay around until
579///       // the semicolon on *this* statement, which is after the await point,
580///       // and the enclosing Future would not implement Send.
581///       log(make_error!("look: {:p}", unsync())).await;
582///   }
583///
584///   async fn log(error: Error) {/* ... */}
585///
586///   // Returns something without a Sync impl.
587///   fn unsync() -> *const () {
588///       0 as *const ()
589///   }
590///   #
591///   # fn test() {
592///   #     fn assert_send(_: impl Send) {}
593///   #     assert_send(f());
594///   # }
595///   ```
596#[unstable(feature = "hint_must_use", issue = "94745")]
597#[must_use] // <-- :)
598#[inline(always)]
599pub const fn must_use<T>(value: T) -> T {
600    value
601}
602
603/// Hints to the compiler that a branch condition is likely to be true.
604/// Returns the value passed to it.
605///
606/// It can be used with `if` or boolean `match` expressions.
607///
608/// When used outside of a branch condition, it may still influence a nearby branch, but
609/// probably will not have any effect.
610///
611/// It can also be applied to parts of expressions, such as `likely(a) && unlikely(b)`, or to
612/// compound expressions, such as `likely(a && b)`. When applied to compound expressions, it has
613/// the following effect:
614/// ```text
615///     likely(!a) => !unlikely(a)
616///     likely(a && b) => likely(a) && likely(b)
617///     likely(a || b) => a || likely(b)
618/// ```
619///
620/// See also the function [`cold_path()`] which may be more appropriate for idiomatic Rust code.
621///
622/// # Examples
623///
624/// ```
625/// #![feature(likely_unlikely)]
626/// use core::hint::likely;
627///
628/// fn foo(x: i32) {
629///     if likely(x > 0) {
630///         println!("this branch is likely to be taken");
631///     } else {
632///         println!("this branch is unlikely to be taken");
633///     }
634///
635///     match likely(x > 0) {
636///         true => println!("this branch is likely to be taken"),
637///         false => println!("this branch is unlikely to be taken"),
638///     }
639///
640///     // Use outside of a branch condition may still influence a nearby branch
641///     let cond = likely(x != 0);
642///     if cond {
643///         println!("this branch is likely to be taken");
644///     }
645/// }
646/// ```
647///
648///
649#[unstable(feature = "likely_unlikely", issue = "136873")]
650#[inline(always)]
651pub const fn likely(b: bool) -> bool {
652    crate::intrinsics::likely(b)
653}
654
655/// Hints to the compiler that a branch condition is unlikely to be true.
656/// Returns the value passed to it.
657///
658/// It can be used with `if` or boolean `match` expressions.
659///
660/// When used outside of a branch condition, it may still influence a nearby branch, but
661/// probably will not have any effect.
662///
663/// It can also be applied to parts of expressions, such as `likely(a) && unlikely(b)`, or to
664/// compound expressions, such as `unlikely(a && b)`. When applied to compound expressions, it has
665/// the following effect:
666/// ```text
667///     unlikely(!a) => !likely(a)
668///     unlikely(a && b) => a && unlikely(b)
669///     unlikely(a || b) => unlikely(a) || unlikely(b)
670/// ```
671///
672/// See also the function [`cold_path()`] which may be more appropriate for idiomatic Rust code.
673///
674/// # Examples
675///
676/// ```
677/// #![feature(likely_unlikely)]
678/// use core::hint::unlikely;
679///
680/// fn foo(x: i32) {
681///     if unlikely(x > 0) {
682///         println!("this branch is unlikely to be taken");
683///     } else {
684///         println!("this branch is likely to be taken");
685///     }
686///
687///     match unlikely(x > 0) {
688///         true => println!("this branch is unlikely to be taken"),
689///         false => println!("this branch is likely to be taken"),
690///     }
691///
692///     // Use outside of a branch condition may still influence a nearby branch
693///     let cond = unlikely(x != 0);
694///     if cond {
695///         println!("this branch is likely to be taken");
696///     }
697/// }
698/// ```
699#[unstable(feature = "likely_unlikely", issue = "136873")]
700#[inline(always)]
701pub const fn unlikely(b: bool) -> bool {
702    crate::intrinsics::unlikely(b)
703}
704
705/// Hints to the compiler that given path is cold, i.e., unlikely to be taken. The compiler may
706/// choose to optimize paths that are not cold at the expense of paths that are cold.
707///
708/// # Examples
709///
710/// ```
711/// #![feature(cold_path)]
712/// use core::hint::cold_path;
713///
714/// fn foo(x: &[i32]) {
715///     if let Some(first) = x.get(0) {
716///         // this is the fast path
717///     } else {
718///         // this path is unlikely
719///         cold_path();
720///     }
721/// }
722///
723/// fn bar(x: i32) -> i32 {
724///     match x {
725///         1 => 10,
726///         2 => 100,
727///         3 => { cold_path(); 1000 }, // this branch is unlikely
728///         _ => { cold_path(); 10000 }, // this is also unlikely
729///     }
730/// }
731/// ```
732#[unstable(feature = "cold_path", issue = "136873")]
733#[inline(always)]
734pub const fn cold_path() {
735    crate::intrinsics::cold_path()
736}