Change:
<!-- Thank you for creating a tracking issue! Tracking issues are for tracking a feature from implementation to stabilization. Make sure to include the relevant RFC for the feature if it has one. If the new feature is small, it may be fine to skip the RFC process. In that case, you can use in your initial implementation PR. The reviewer will ask you to open a tracking issue if they agree your feature can be without an RFC. --Feature gate: This is a tracking issue for ... <!-- Include a short description of the feature. --<!-- For most library features, it'd be useful to include a summarized version of the public API. (E.g. just the public function signatures without their doc comments or implementation.) --<!-- For larger features, more steps might be involved. If the feature is changed later, please add those PRs here as well. --- [x] ACP: [x] Implementation: [ ] Final comment period (FCP)[^1] [ ] Stabilization PR <!-- Once the feature has gone through a few release cycles and there are no unresolved questions left, the feature might be ready for stabilization. If this feature didn't go through the RFC process, a final comment period (FCP) is always needed before stabilization. This works as follows: A library API team member can kick off the stabilization process, at which point the rfcbot will ask all the team members to verify they agree with stabilization. Once enough members agree and there are no concerns, the final comment period begins: this issue will be marked as such and will be listed in the next This Week in Rust newsletter. If no blocking concerns are raised in that period of 10 days, a stabilization PR can be opened by anyone. --<!-- Include any open questions that need to be answered before the feature can be stabilised. If multiple (unrelated) big questions come up, it can be a good idea to open a separate issue for each, to make it easier to keep track of the discussions. It's useful to link any relevant discussions and conclusions (whether on GitHub, Zulip, or the internals forum) here. --- [x] Naming, as always: [^1]: https://std-dev-
Hello libs-api folks! I'm nominating this (at low priority) because when the open issue is the name, I think it mostly needs your input to make progress.
What if the name was ?
We discussed this in the libs-api meeting and we're happy with because it follows the existing pattern of functions in the standard library. fcp merge
Team member has proposed to merge this. The next step is review by the rest of the tagged team members: [x] [x] [x] [ ] [x] Concerns: resolved by Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See for info about what commands tagged team members can give me.
Todo list: docs could use an example (+1 for the name since it likely enables the same optimizations as )
concern doc-example I agree that we should have a doc example showing when someone might want to use this method. The docs otherwise look good as written!
Suggestion for doc example: show example implementation of ?
Could emit when debug assertions are disabled? looks like a case where assuming the unsafe preconditions would have led to more efficient codegen, I am sure there are others. Edit: I guess calls so calling would be correct.
I am unsure whether the FCP at was purely for the unstable name change or an intent to stabilize; assuming the latter, I created a stabilization PR at That PR should also resolve the docs example concern.
The problem is that all those extra s in codegen have pretty high compile-time cost, and because they change inlining metrics can actually make runtime performance worse.
resolve doc-example
:bell: This is now entering its final comment period, as per the . :bell:
The final comment period, with a disposition to merge, as per the , is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon.
What happens if the expression passed to assert_unchecked has a side effect? I could not find a clear answer in the current documentation.
is an ordinary function, not a macro. There's only a value passed to it; it works like a call to any other function.
In that case I think the documentation could use a clarification on a few related points: The documentation for builtinassume explicitly states that side effects of the expression passed to it are discarded. If this is not the case for assertunchecked then that difference should probably be highlighted, since the documentation for assertunchecked implies that assertunchecked and builtinassume are equivalent. Is the expression passed to assertunchecked likely/guaranteed to be optimized out in a release compile if it has no side effects? This could matter quite a bit for microoptimizations.
If there are no other uses? Probably, at some point in the optimization pipeline. But up to that point the expression is preserved which can affect earlier optimizations. Which is one of the reasons why the docs say The usual approach is to benchmark, look at the assembly or look at the LLVM IR after optimizations to see if it's worthwhile. Blind applications of the hint are discouraged.
Closing as completed by .

Discussion:
} } <ins> /// Makes a *soundness* promise to the compiler that `cond` holds. /// /// This may allow the optimizer to simplify things, /// but it might also make the generated code slower. /// Either way, calling it will most likely make compilation take longer. /// /// This is a situational tool for micro-optimization, and is allowed to do nothing. /// Any use should come with a repeatable benchmark to show the value /// and allow removing it later should the optimizer get smarter and no longer need it. /// /// The more complicated the condition the less likely this is to be fruitful. /// For example, `assert_unchecked(foo.is_sorted())` is a complex enough value /// that the compiler is unlikely to be able to take advantage of it. /// /// There's also no need to `assert_unchecked` basic properties of things.  For /// example, the compiler already knows the range of `count_ones`, so there's no /// benefit to `let n = u32::count_ones(x); assert_unchecked(n <= u32::BITS);`. /// /// If ever you're tempted to write `assert_unchecked(false)`, then you're /// actually looking for [`unreachable_unchecked()`]. /// /// You may know this from other places /// as [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic) /// or [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume). /// /// This promotes a correctness requirement to a soundness requirement. /// Don't do that without very good reason. /// /// # Safety /// /// `cond` must be `true`.  It's immediate UB to call this with `false`. /// #[inline(always)] #[doc(alias = "assume")] #[track_caller] #[unstable(feature = "hint_assert_unchecked", issue = "119131")] #[rustc_const_unstable(feature = "const_hint_assert_unchecked", issue = "119131")] pub const unsafe fn assert_unchecked(cond: bool) { // SAFETY: The caller promised `cond` is true. unsafe { intrinsics::assert_unsafe_precondition!( "hint::assert_unchecked must never be called when the condition is false", (cond: bool) => cond, ); crate::intrinsics::assume(cond); } } </ins> /// Emits a machine instruction to signal the processor that it is running in /// a busy-wait spin-loop ("spin lock"). ///

/// the occasional mistake, and this check should help them figure things out. #[allow_internal_unstable(const_eval_select)] // permit this to be called in stably-const fn macro_rules! assert_unsafe_precondition { <del> ($name:expr, $([$($tt:tt)*])?($($i:ident:$ty:ty),*$(,)?) => $e:expr) => { </del> <ins> ($name:expr, $([$($tt:tt)*])?($($i:ident:$ty:ty),*$(,)?) => $e:expr $(,)?) => { </ins> if cfg!(debug_assertions) { // allow non_snake_case to allow capturing const generics #[allow(non_snake_case)]

<ins> #![feature(hint_assert_unchecked)] #![feature(const_hint_assert_unchecked)] const _: () = unsafe { let n = u32::MAX.count_ones(); std::hint::assert_unchecked(n < 32); //~ ERROR evaluation of constant value failed }; fn main() { } </ins>

<ins> error[E0080]: evaluation of constant value failed --> $DIR/const-assert-unchecked-ub.rs:6:5 | LL |     std::hint::assert_unchecked(n < 32); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `assume` called with `false` error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0080`. </ins>