const select_unpredictable

This commit is contained in:
ltdk
2025-10-14 20:23:39 -04:00
parent f37aa9955f
commit 6f649e4e1a
5 changed files with 35 additions and 16 deletions

View File

@@ -4,6 +4,7 @@
//! //!
//! Hints may be compile time or runtime. //! Hints may be compile time or runtime.
use crate::marker::Destruct;
use crate::mem::MaybeUninit; use crate::mem::MaybeUninit;
use crate::{intrinsics, ub_checks}; use crate::{intrinsics, ub_checks};
@@ -771,7 +772,11 @@ pub const fn cold_path() {
/// ``` /// ```
#[inline(always)] #[inline(always)]
#[stable(feature = "select_unpredictable", since = "1.88.0")] #[stable(feature = "select_unpredictable", since = "1.88.0")]
pub fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T { #[rustc_const_unstable(feature = "const_select_unpredictable", issue = "145938")]
pub const fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T
where
T: [const] Destruct,
{
// FIXME(https://github.com/rust-lang/unsafe-code-guidelines/issues/245): // FIXME(https://github.com/rust-lang/unsafe-code-guidelines/issues/245):
// Change this to use ManuallyDrop instead. // Change this to use ManuallyDrop instead.
let mut true_val = MaybeUninit::new(true_val); let mut true_val = MaybeUninit::new(true_val);

View File

@@ -55,7 +55,7 @@
#![allow(missing_docs)] #![allow(missing_docs)]
use crate::ffi::va_list::{VaArgSafe, VaListImpl}; use crate::ffi::va_list::{VaArgSafe, VaListImpl};
use crate::marker::{ConstParamTy, DiscriminantKind, PointeeSized, Tuple}; use crate::marker::{ConstParamTy, Destruct, DiscriminantKind, PointeeSized, Tuple};
use crate::ptr; use crate::ptr;
mod bounds; mod bounds;
@@ -477,11 +477,15 @@ pub const fn unlikely(b: bool) -> bool {
/// However unlike the public form, the intrinsic will not drop the value that /// However unlike the public form, the intrinsic will not drop the value that
/// is not selected. /// is not selected.
#[unstable(feature = "core_intrinsics", issue = "none")] #[unstable(feature = "core_intrinsics", issue = "none")]
#[rustc_const_unstable(feature = "const_select_unpredictable", issue = "145938")]
#[rustc_intrinsic] #[rustc_intrinsic]
#[rustc_nounwind] #[rustc_nounwind]
#[miri::intrinsic_fallback_is_spec] #[miri::intrinsic_fallback_is_spec]
#[inline] #[inline]
pub fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T { pub const fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T
where
T: [const] Destruct,
{
if b { true_val } else { false_val } if b { true_val } else { false_val }
} }

View File

@@ -106,6 +106,7 @@
#![feature(const_cmp)] #![feature(const_cmp)]
#![feature(const_destruct)] #![feature(const_destruct)]
#![feature(const_eval_select)] #![feature(const_eval_select)]
#![feature(const_select_unpredictable)]
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(coverage_attribute)] #![feature(coverage_attribute)]
#![feature(disjoint_bitor)] #![feature(disjoint_bitor)]

View File

@@ -1,25 +1,33 @@
#[test] #[test]
fn select_unpredictable_drop() { fn select_unpredictable_drop() {
use core::cell::Cell; use core::cell::Cell;
struct X<'a>(&'a Cell<bool>); struct X<'a>(&'a Cell<bool>);
impl Drop for X<'_> { impl const Drop for X<'_> {
fn drop(&mut self) { fn drop(&mut self) {
self.0.set(true); self.0.set(true);
} }
} }
let a_dropped = Cell::new(false); const fn do_test() {
let b_dropped = Cell::new(false); let a_dropped = Cell::new(false);
let a = X(&a_dropped); let b_dropped = Cell::new(false);
let b = X(&b_dropped); let a = X(&a_dropped);
assert!(!a_dropped.get()); let b = X(&b_dropped);
assert!(!b_dropped.get()); assert!(!a_dropped.get());
let selected = core::hint::select_unpredictable(core::hint::black_box(true), a, b); assert!(!b_dropped.get());
assert!(!a_dropped.get()); let selected = core::hint::select_unpredictable(core::hint::black_box(true), a, b);
assert!(b_dropped.get()); assert!(!a_dropped.get());
drop(selected); assert!(b_dropped.get());
assert!(a_dropped.get()); drop(selected);
assert!(b_dropped.get()); assert!(a_dropped.get());
assert!(b_dropped.get());
}
do_test();
const {
do_test();
}
} }
#[test] #[test]

View File

@@ -27,6 +27,7 @@
#![feature(const_option_ops)] #![feature(const_option_ops)]
#![feature(const_ref_cell)] #![feature(const_ref_cell)]
#![feature(const_result_trait_fn)] #![feature(const_result_trait_fn)]
#![feature(const_select_unpredictable)]
#![feature(const_trait_impl)] #![feature(const_trait_impl)]
#![feature(control_flow_ok)] #![feature(control_flow_ok)]
#![feature(core_float_math)] #![feature(core_float_math)]