const select_unpredictable
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
Reference in New Issue
Block a user