Performance assertions

We can use std::hint::unreachable_unchecked to give the compiler hints about what is/isn’t true. Should we add a wrapper macro (e.g. std::hint::performance_assert!) for assertions that check their arguments in debug mode, but in release mode will cause the compiler to assume they’re true?

Of course this macro would only be usable in unsafe mode.

An example implementation with a motivating snippet: https://rust.godbolt.org/z/0AzKfM.

https://crates.io/crates/new_debug_unreachable

Currently it’s problematic to use debug asserts in std, see this issue:

Hopefully RFC 2663 will change that.

A macro would not have this problem, since the expansion would happen in user code. (This is how the std::debug_assert macro works.)

This macro is simple to implement and can already be implemented in stable Rust in user code (as shown in the OP). Given this, and the relative footgun nature of using this macro, I think it’s best to not put this in std and instead require users to implement it themselves if they really want it.

I disagree. The status-quo is std::hint::unreachable_unchecked. If someone is looking to perform an optimization like this, that is what they will reach for. That macro is more dangerous than this one, since even in debug mode it will cause UB rather than panic.

There’s another possibility here: make this not UB in debug mode.

The current implementation, in fact, already guards against getting it wrong. If you compile the following:

pub unsafe fn force_unwrap(x: Option<i32>) -> i32 {
    match x {
        Some(y) => y,
        _ => std::hint::unreachable_unchecked(),
    }
}

You’ll see the following:

core::hint::unreachable_unchecked:
.Lfunc_begin0:
	.file	1 "/rustc/91856ed52c58aa5ba66a015354d1cc69e9779bdf/src/libcore/hint.rs"
	.loc	1 49 0
	.cfi_startproc
	.loc	1 50 4 prologue_end
	ud2

Where if that function actually gets called, it’ll trigger an invalid opcode exception, stopping the program (in a way that your debugger will hopefully get the callstack).

Details:

1 Like

I think making std::hint::unreachable_unchecked panic in debug mode is a good idea.

I don’t think that we should add macro just because Rust currently does not support automatic std recompiling with enabled debug assertions. And it’s only one case where debug asserts in std will be useful, as the previously linked issue demonstrates. Should we add macros for every other case as well? Highly doubt it.

1 Like