branches/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![doc = include_str!("../README.md")]
3#![warn(missing_docs, missing_debug_implementations)]
4
5/// Provides branch detection functions for Rust, using built-in Rust features
6/// on stable and core::intrinsics on nightly.
7#[cfg(feature = "nightly")]
8pub use core::intrinsics::{abort, assume, likely, unlikely};
9
10// No one like to visit this function
11#[cfg(not(feature = "nightly"))]
12#[inline(always)]
13#[cold]
14fn cold_and_empty() {}
15
16/// Aborts the execution of the process immediately and without any cleanup.
17///
18/// This function is used to indicate a critical and unrecoverable error in the program.
19/// It terminates the process immediately without performing any cleanup or running destructors.
20///
21/// This function is safe to call, so it does not require an unsafe block.
22/// Therefore, implementations must not require the user to uphold any safety invariants.
23///
24/// If the std feature is enabled, this function calls std::process::abort()
25/// which is a more user-friendly and stable way of aborting the process.
26///
27/// If the std feature is disabled, this function panics by calling panic!().
28/// In this case, by using `extern "C"` this function is guaranteed to not unwind.
29#[cfg(not(feature = "nightly"))]
30#[cold]
31pub extern "C" fn abort() -> ! {
32    #[cfg(not(feature = "std"))]
33    #[inline(always)]
34    fn _abort() -> ! {
35        panic!()
36    }
37    #[cfg(feature = "std")]
38    #[inline(always)]
39    fn _abort() -> ! {
40        std::process::abort()
41    }
42    _abort()
43}
44
45/// Informs the optimizer that a condition is always true.
46///
47/// If the condition is actually false, the behavior is undefined.
48///
49/// This intrinsic doesn't generate any code. Instead, it tells the optimizer
50/// to preserve the condition for optimization passes. This can interfere with
51/// optimization of surrounding code and reduce performance, so avoid using it
52/// if the optimizer can already discover the invariant on its own or if it
53/// doesn't enable any significant optimizations.
54///
55/// # Safety
56///
57/// This intrinsic is marked unsafe because it can result in undefined behavior
58/// if the condition passed to it is false.
59#[cfg(not(feature = "nightly"))]
60#[inline(always)]
61pub unsafe fn assume(b: bool) {
62    if !b {
63        core::hint::unreachable_unchecked();
64    }
65}
66
67/// Hints to the compiler that the branch condition is likely to be true.
68/// Returns the value passed to it.
69///
70/// This intrinsic is primarily used with `if` statements.
71/// Using it in other contexts may not have any effect.
72///
73/// Unlike most intrinsics, this function is safe to call and doesn't require an `unsafe` block.
74/// Therefore, implementations must not require the user to uphold any safety invariants.
75#[cfg(not(feature = "nightly"))]
76#[inline(always)]
77pub fn likely(b: bool) -> bool {
78    if !b {
79        cold_and_empty();
80    }
81    b
82}
83
84/// Hints to the compiler that the branch condition is unlikely to be true.
85/// Returns the value passed to it.
86///
87/// This intrinsic is primarily used with `if` statements.
88/// Using it in other contexts may not have any effect.
89///
90/// Unlike most intrinsics, this function is safe to call and doesn't require an `unsafe` block.
91/// Therefore, implementations must not require the user to uphold any safety invariants.
92#[cfg(not(feature = "nightly"))]
93#[inline(always)]
94pub fn unlikely(b: bool) -> bool {
95    if b {
96        cold_and_empty();
97    }
98    b
99}