Could `unlikely` and `likely` be stabilized in `std::hint`?

The unlikely or likely could be stabilized as macros to hint compiler about branch prediction heuristics. That would make porting some C libraries to Rust more natural.

Related discussions

9 Likes

This reminds me of https://users.rust-lang.org/t/how-expensive-is-rc-refcell-borrow-mut/26713/4

I don’t know enough of the internals so maybe this is already the case, but when a branch leads to a panic (such as when calling .borrow_mut() while a borrow is already held), then it seems to me that tagging these branches as unlikely could improve the performance of bug-free programs.


Aside

Could ::std::hint::unreachable_unchecked() include something like

#[cfg(debug_assertions)] {
    unreachable!(concat!(
        "This is a very serious soundness hole, "
        "submitting an issue to the developers would be really appreciated",
    ));
}

?

I’m skeptical about stabilizing unlikely and likely as-is. It doesn’t seem like the right interface and is not general enough to fit pattern matching. (and iirc there were other problems? cc @nagisa)

A better interface would be something akin to this GHC proposal:

Basically, we’d allow the user to write:

match foo {
    arm => {
        #![bikeshed = 5]
        // logic
    },
    arm => {
        // logic
    },
}

if somecondition {
    #![bikeshed = 4]
    // logic
} else if othercondition {
    #![bikeshed = 2]
    // logic
} else {
    #![bikeshed] // Same as `#![bikeshed = 1]`
}

As a sugar for the first match we’d also allow:

match foo {
    #[bikeshed = 5]
    arm => /* logic */,
    arm => /* logic */,
}

Here bikeshed could be likely or something.

5 Likes

panic is already marked as #[cold], which tells the optimizer to treat any branch that panics as unlikely.

For now the new_debug_unreachable crate has a macro that does this.

2 Likes

soundness hole

Nitpick: I think "soundness hole" is the wrong word here; better to say UB, because this is LLVM UB, not just Rust UB. "Soundness" is almost always referring to a static check failure, and unreachable_unchecked exists outside of any Rust static checking.

I think he was just giving an example of an error message that a dev might put, not that using unreachable_unchecked is in itself unsound. Rather that if that branch is ever reached on a debug build, then it would trigger the panic and ask the user to tell the dev about the bug, which the dev has chosen to label as a soundness-hole.

1 Like

I’m quite unsure if I want to see this in the language or not.

In particular, the compiler is almost always more right than the programmers intuition. And as with #[inline], these annotations might make the performance worse if applied in a wrong way. Not having it prevents people from overusing it and shooting themselves in the foot.

On the other hand, there are some times when the compiler is not right.

Given their existence in C and necessity in high performance C, I don't think we can consider this an optional feature.

5 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.