Skip to content

Commit 83ed082

Browse files
committed
Export likely(), unlikely() and cold_path() in std::hint
1 parent b1f3a26 commit 83ed082

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

core/src/hint.rs

+140
Original file line numberDiff line numberDiff line change
@@ -511,3 +511,143 @@ pub const fn black_box<T>(dummy: T) -> T {
511511
pub const fn must_use<T>(value: T) -> T {
512512
value
513513
}
514+
515+
/// Hints to the compiler that a branch condition is likely to be true.
516+
/// Returns the value passed to it.
517+
///
518+
/// It can be used with `if` or boolean `match` expressions.
519+
///
520+
/// When used outside of a branch condition, it may still work if there is a branch close by, but
521+
/// it is not guaranteed to have any effect.
522+
///
523+
/// It can also be applied to parts of expressions, such as `likely(a) && unlikely(b)`, or to
524+
/// compound expressions, such as `likely(a && b)`. When applied to compound expressions, it has
525+
/// the following effect:
526+
/// ```text
527+
/// likely(!a) => !unlikely(a)
528+
/// likely(a && b) => likely(a) && likely(b)
529+
/// likely(a || b) => a || likely(b)
530+
/// ```
531+
///
532+
/// See also the function [`cold_path()`] which may be more appropriate for idiomatic Rust code.
533+
///
534+
/// # Examples
535+
///
536+
/// ```
537+
/// #![feature(likely_unlikely)]
538+
/// use core::hint::likely;
539+
///
540+
/// fn foo(x: i32) {
541+
/// if likely(x > 0) {
542+
/// println!("this branch is likely to be taken");
543+
/// } else {
544+
/// println!("this branch is unlikely to be taken");
545+
/// }
546+
///
547+
/// match likely(x > 0) {
548+
/// true => println!("this branch is likely to be taken"),
549+
/// false => println!("this branch is unlikely to be taken"),
550+
/// }
551+
///
552+
/// // Use outside of a branch condition. This may still work if there is a branch close by,
553+
/// // but it is not guaranteed to have any effect
554+
/// let cond = likely(x != 0);
555+
/// if cond {
556+
/// println!("this branch is likely to be taken");
557+
/// }
558+
/// }
559+
/// ```
560+
///
561+
///
562+
#[unstable(feature = "likely_unlikely", issue = "26179")]
563+
#[rustc_nounwind]
564+
#[inline(always)]
565+
pub const fn likely(b: bool) -> bool {
566+
crate::intrinsics::likely(b)
567+
}
568+
569+
/// Hints to the compiler that a branch condition is unlikely to be true.
570+
/// Returns the value passed to it.
571+
///
572+
/// It can be used with `if` or boolean `match` expressions.
573+
///
574+
/// When used outside of a branch condition, it may still work if there is a branch close by, but
575+
/// it is not guaranteed to have any effect.
576+
///
577+
/// It can also be applied to parts of expressions, such as `likely(a) && unlikely(b)`, or to
578+
/// compound expressions, such as `unlikely(a && b)`. When applied to compound expressions, it has
579+
/// the following effect:
580+
/// ```text
581+
/// unlikely(!a) => !likely(a)
582+
/// unlikely(a && b) => a && unlikely(b)
583+
/// unlikely(a || b) => unlikely(a) || unlikely(b)
584+
/// ```
585+
///
586+
/// See also the function [`cold_path()`] which may be more appropriate for idiomatic Rust code.
587+
///
588+
/// # Examples
589+
///
590+
/// ```
591+
/// #![feature(likely_unlikely)]
592+
/// use core::hint::unlikely;
593+
///
594+
/// fn foo(x: i32) {
595+
/// if unlikely(x > 0) {
596+
/// println!("this branch is unlikely to be taken");
597+
/// } else {
598+
/// println!("this branch is likely to be taken");
599+
/// }
600+
///
601+
/// match unlikely(x > 0) {
602+
/// true => println!("this branch is unlikely to be taken"),
603+
/// false => println!("this branch is likely to be taken"),
604+
/// }
605+
///
606+
/// // Use outside of a branch condition. This may still work if there is a branch close by,
607+
/// // but it is not guaranteed to have any effect
608+
/// let cond = unlikely(x != 0);
609+
/// if cond {
610+
/// println!("this branch is likely to be taken");
611+
/// }
612+
/// }
613+
/// ```
614+
#[unstable(feature = "likely_unlikely", issue = "26179")]
615+
#[rustc_nounwind]
616+
#[inline(always)]
617+
pub const fn unlikely(b: bool) -> bool {
618+
crate::intrinsics::unlikely(b)
619+
}
620+
621+
/// Hints to the compiler that given path is cold, i.e., unlikely to be taken. The compiler may
622+
/// choose to optimize paths that are not cold at the expense of paths that are cold.
623+
///
624+
/// # Examples
625+
///
626+
/// ```
627+
/// #![feature(cold_path)]
628+
/// use core::hint::cold_path;
629+
///
630+
/// fn foo(x: &[i32]) {
631+
/// if let Some(first) = x.get(0) {
632+
/// // this is the fast path
633+
/// } else {
634+
/// // this path is unlikely
635+
/// cold_path();
636+
/// }
637+
/// }
638+
///
639+
/// fn bar(x: i32) -> i32 {
640+
/// match x {
641+
/// 1 => 10,
642+
/// 2 => 100,
643+
/// 3 => { cold_path(); 1000 }, // this branch is unlikely
644+
/// _ => { cold_path(); 10000 }, // this is also unlikely
645+
/// }
646+
/// }
647+
/// ```
648+
#[unstable(feature = "cold_path", issue = "26179")]
649+
#[rustc_nounwind]
650+
#[inline(always)]
651+
pub const fn cold_path() {
652+
crate::intrinsics::cold_path()
653+
}

0 commit comments

Comments
 (0)