diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs index 757034fe30a5e..f95635370dc3b 100644 --- a/compiler/rustc_middle/src/mir/consts.rs +++ b/compiler/rustc_middle/src/mir/consts.rs @@ -325,6 +325,9 @@ impl<'tcx> Const<'tcx> { match c.kind() { ConstKind::Value(ty, val) => Ok(tcx.valtree_to_const_val((ty, val))), + ConstKind::Expr(_) => { + bug!("Normalization of `ty::ConstKind::Expr` is unimplemented") + } _ => Err(tcx.dcx().delayed_bug("Unevaluated `ty::Const` in MIR body").into()), } } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 17636d432aeed..fe90066b4e7e1 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -578,16 +578,28 @@ pub fn try_evaluate_const<'tcx>( (args, param_env) } } - } else { - // FIXME: We don't check anything on stable as the only way we can wind up with - // an unevaluated constant containing generic parameters is through array repeat - // expression counts which have a future compat lint for usage of generic parameters - // instead of a hard error. + } else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() { + // FIXME: remove this when `const_evaluatable_unchecked` is a hard error. + // + // Diagnostics will sometimes replace the identity args of anon consts in + // array repeat expr counts with inference variables so we have to handle this + // even though it is not something we should ever actually encounter. // - // This codepath is however also reachable by `generic_const_exprs` and some other - // feature gates which allow constants in the type system to use generic parameters. - // In theory we should be checking for generic parameters here and returning an error - // in such cases. + // Array repeat expr counts are allowed to syntactically use generic parameters + // but must not actually depend on them in order to evalaute succesfully. This means + // that it is actually fine to evalaute them in their own environment rather than with + // the actually provided generic arguments. + tcx.dcx().delayed_bug( + "Encountered anon const with inference variable args but no error reported", + ); + + let args = GenericArgs::identity_for_item(tcx, uv.def); + let param_env = tcx.param_env(uv.def); + (args, param_env) + } else { + // FIXME: This codepath is reachable under `associated_const_equality` and in the + // future will be reachable by `min_generic_const_args`. We should handle inference + // variables and generic parameters properly instead of doing nothing. (uv.args, param_env) }; let uv = ty::UnevaluatedConst::new(uv.def, args); diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index c5024a05ed631..bb6dd1d2d30c5 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -1735,7 +1735,7 @@ impl Clone for Box { // Pre-allocate memory to allow writing the cloned value directly. let mut boxed = Self::new_uninit_in(self.1.clone()); unsafe { - (**self).clone_to_uninit(boxed.as_mut_ptr()); + (**self).clone_to_uninit(boxed.as_mut_ptr().cast()); boxed.assume_init() } } diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 55649d865fc63..66353ccfa47d3 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -289,40 +289,12 @@ impl Clone for BTreeMap { } } -impl super::Recover for BTreeMap -where - K: Borrow + Ord, - Q: Ord, -{ - type Key = K; - - fn get(&self, key: &Q) -> Option<&K> { - let root_node = self.root.as_ref()?.reborrow(); - match root_node.search_tree(key) { - Found(handle) => Some(handle.into_kv().0), - GoDown(_) => None, - } - } - - fn take(&mut self, key: &Q) -> Option { - let (map, dormant_map) = DormantMutRef::new(self); - let root_node = map.root.as_mut()?.borrow_mut(); - match root_node.search_tree(key) { - Found(handle) => Some( - OccupiedEntry { - handle, - dormant_map, - alloc: (*map.alloc).clone(), - _marker: PhantomData, - } - .remove_kv() - .0, - ), - GoDown(_) => None, - } - } - - fn replace(&mut self, key: K) -> Option { +/// Internal functionality for `BTreeSet`. +impl BTreeMap { + pub(super) fn replace(&mut self, key: K) -> Option + where + K: Ord, + { let (map, dormant_map) = DormantMutRef::new(self); let root_node = map.root.get_or_insert_with(|| Root::new((*map.alloc).clone())).borrow_mut(); diff --git a/library/alloc/src/collections/btree/mod.rs b/library/alloc/src/collections/btree/mod.rs index c7d0144de30cb..b8667d09c33b3 100644 --- a/library/alloc/src/collections/btree/mod.rs +++ b/library/alloc/src/collections/btree/mod.rs @@ -12,11 +12,3 @@ mod search; pub mod set; mod set_val; mod split; - -trait Recover { - type Key; - - fn get(&self, key: &Q) -> Option<&Self::Key>; - fn take(&mut self, key: &Q) -> Option; - fn replace(&mut self, key: Self::Key) -> Option; -} diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index a40209fa2e397..8daee6030c270 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -7,7 +7,6 @@ use core::iter::{FusedIterator, Peekable}; use core::mem::ManuallyDrop; use core::ops::{BitAnd, BitOr, BitXor, Bound, RangeBounds, Sub}; -use super::Recover; use super::map::{BTreeMap, Keys}; use super::merge_iter::MergeIterInner; use super::set_val::SetValZST; @@ -635,7 +634,7 @@ impl BTreeSet { T: Borrow + Ord, Q: Ord, { - Recover::get(&self.map, value) + self.map.get_key_value(value).map(|(k, _)| k) } /// Returns `true` if `self` has no elements in common with `other`. @@ -926,7 +925,7 @@ impl BTreeSet { where T: Ord, { - Recover::replace(&mut self.map, value) + self.map.replace(value) } /// If the set contains an element equal to the value, removes it from the @@ -978,7 +977,7 @@ impl BTreeSet { T: Borrow + Ord, Q: Ord, { - Recover::take(&mut self.map, value) + self.map.remove_entry(value).map(|(k, _)| k) } /// Retains only the elements specified by the predicate. diff --git a/library/alloc/src/collections/btree/set_val.rs b/library/alloc/src/collections/btree/set_val.rs index 80c459bcf81db..cf30160bfbbc2 100644 --- a/library/alloc/src/collections/btree/set_val.rs +++ b/library/alloc/src/collections/btree/set_val.rs @@ -3,14 +3,14 @@ /// * `BTreeMap` (possible user-defined map) /// * `BTreeMap` (internal set representation) #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Clone, Default)] -pub struct SetValZST; +pub(super) struct SetValZST; /// A trait to differentiate between `BTreeMap` and `BTreeSet` values. /// Returns `true` only for type `SetValZST`, `false` for all other types (blanket implementation). /// `TypeId` requires a `'static` lifetime, use of this trait avoids that restriction. /// /// [`TypeId`]: std::any::TypeId -pub trait IsSetVal { +pub(super) trait IsSetVal { fn is_set_val() -> bool; } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 4718264e68590..3a9bd1b5bf119 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -1876,7 +1876,7 @@ impl Rc { // Initialize with clone of this. let initialized_clone = unsafe { // Clone. If the clone panics, `in_progress` will be dropped and clean up. - this_data_ref.clone_to_uninit(in_progress.data_ptr()); + this_data_ref.clone_to_uninit(in_progress.data_ptr().cast()); // Cast type of pointer, now that it is initialized. in_progress.into_rc() }; diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 8520c3c196b1b..da2d6bb3bce24 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2272,7 +2272,7 @@ impl Arc { let initialized_clone = unsafe { // Clone. If the clone panics, `in_progress` will be dropped and clean up. - this_data_ref.clone_to_uninit(in_progress.data_ptr()); + this_data_ref.clone_to_uninit(in_progress.data_ptr().cast()); // Cast type of pointer, now that it is initialized. in_progress.into_arc() }; diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs index c5f8bd7401e5e..ec1aed53eaf72 100644 --- a/library/core/src/clone.rs +++ b/library/core/src/clone.rs @@ -232,20 +232,20 @@ pub struct AssertParamIsCopy { pub unsafe trait CloneToUninit { /// Performs copy-assignment from `self` to `dst`. /// - /// This is analogous to `std::ptr::write(dst, self.clone())`, + /// This is analogous to `std::ptr::write(dst.cast(), self.clone())`, /// except that `self` may be a dynamically-sized type ([`!Sized`](Sized)). /// /// Before this function is called, `dst` may point to uninitialized memory. /// After this function is called, `dst` will point to initialized memory; it will be - /// sound to create a `&Self` reference from the pointer. + /// sound to create a `&Self` reference from the pointer with the [pointer metadata] + /// from `self`. /// /// # Safety /// /// Behavior is undefined if any of the following conditions are violated: /// - /// * `dst` must be [valid] for writes. - /// * `dst` must be properly aligned. - /// * `dst` must have the same [pointer metadata] (slice length or `dyn` vtable) as `self`. + /// * `dst` must be [valid] for writes for `std::mem::size_of_val(self)` bytes. + /// * `dst` must be properly aligned to `std::mem::align_of_val(self)`. /// /// [valid]: crate::ptr#safety /// [pointer metadata]: crate::ptr::metadata() @@ -266,15 +266,15 @@ pub unsafe trait CloneToUninit { /// that might have already been created. (For example, if a `[Foo]` of length 3 is being /// cloned, and the second of the three calls to `Foo::clone()` unwinds, then the first `Foo` /// cloned should be dropped.) - unsafe fn clone_to_uninit(&self, dst: *mut Self); + unsafe fn clone_to_uninit(&self, dst: *mut u8); } #[unstable(feature = "clone_to_uninit", issue = "126799")] unsafe impl CloneToUninit for T { #[inline] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { + unsafe fn clone_to_uninit(&self, dst: *mut u8) { // SAFETY: we're calling a specialization with the same contract - unsafe { ::clone_one(self, dst) } + unsafe { ::clone_one(self, dst.cast::()) } } } @@ -282,7 +282,8 @@ unsafe impl CloneToUninit for T { unsafe impl CloneToUninit for [T] { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { + unsafe fn clone_to_uninit(&self, dst: *mut u8) { + let dst: *mut [T] = dst.with_metadata_of(self); // SAFETY: we're calling a specialization with the same contract unsafe { ::clone_slice(self, dst) } } @@ -292,21 +293,21 @@ unsafe impl CloneToUninit for [T] { unsafe impl CloneToUninit for str { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { + unsafe fn clone_to_uninit(&self, dst: *mut u8) { // SAFETY: str is just a [u8] with UTF-8 invariant - unsafe { self.as_bytes().clone_to_uninit(dst as *mut [u8]) } + unsafe { self.as_bytes().clone_to_uninit(dst) } } } #[unstable(feature = "clone_to_uninit", issue = "126799")] unsafe impl CloneToUninit for crate::ffi::CStr { #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { + unsafe fn clone_to_uninit(&self, dst: *mut u8) { // SAFETY: For now, CStr is just a #[repr(trasnsparent)] [c_char] with some invariants. // And we can cast [c_char] to [u8] on all supported platforms (see: to_bytes_with_nul). - // The pointer metadata properly preserves the length (NUL included). + // The pointer metadata properly preserves the length (so NUL is also copied). // See: `cstr_metadata_is_length_with_nul` in tests. - unsafe { self.to_bytes_with_nul().clone_to_uninit(dst as *mut [u8]) } + unsafe { self.to_bytes_with_nul().clone_to_uninit(dst) } } } diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index c70dbf54304de..04230b1610aae 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -13,7 +13,7 @@ macro_rules! impl_general_format { ($($t:ident)*) => { $(impl GeneralFormat for $t { fn already_rounded_value_should_use_exponential(&self) -> bool { - let abs = $t::abs_private(*self); + let abs = $t::abs(*self); (abs != 0.0 && abs < 1e-4) || abs >= 1e+16 } })* diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 7fe7425fc70a3..72e34e5faf5a7 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -85,830 +85,1304 @@ pub unsafe fn drop_in_place(to_drop: *mut T) { unsafe { crate::ptr::drop_in_place(to_drop) } } -extern "rust-intrinsic" { - // N.B., these intrinsics take raw pointers because they mutate aliased - // memory, which is not valid for either `&` or `&mut`. +// N.B., these intrinsics take raw pointers because they mutate aliased +// memory, which is not valid for either `&` or `&mut`. - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Relaxed`] as both the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_relaxed_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_relaxed_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_relaxed_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_acquire_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Acquire`] as both the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_acquire_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_release_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_release_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_acqrel_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_acqrel_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_acqrel_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_seqcst_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_seqcst_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange` method by passing - /// [`Ordering::SeqCst`] as both the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange`]. - #[rustc_nounwind] - pub fn atomic_cxchg_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Relaxed`] as both the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_relaxed_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_relaxed_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_relaxed_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_acquire_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Acquire`] as both the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_acquire_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_acquire_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_release_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_release_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_release_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_acqrel_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_acqrel_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_acqrel_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_seqcst_relaxed(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_seqcst_acquire(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange` method by passing +/// [`Ordering::SeqCst`] as both the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchg_seqcst_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Relaxed`] as both the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_relaxed_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_relaxed_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_relaxed_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_acquire_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Acquire`] as both the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_acquire_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_acquire_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_release_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_release_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_release_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_acqrel_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_acqrel_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_acqrel_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_seqcst_relaxed(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_seqcst_acquire(dst: *mut T, old: T, src: T) -> (T, bool); - /// Stores a value if the current value is the same as the `old` value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `compare_exchange_weak` method by passing - /// [`Ordering::SeqCst`] as both the success and failure parameters. - /// For example, [`AtomicBool::compare_exchange_weak`]. - #[rustc_nounwind] - pub fn atomic_cxchgweak_seqcst_seqcst(dst: *mut T, old: T, src: T) -> (T, bool); +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Relaxed`] as both the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_relaxed_relaxed( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Relaxed`] and [`Ordering::Acquire`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_relaxed_acquire( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Relaxed`] and [`Ordering::SeqCst`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_relaxed_seqcst( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Acquire`] and [`Ordering::Relaxed`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_acquire_relaxed( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Acquire`] as both the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_acquire_acquire( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Acquire`] and [`Ordering::SeqCst`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_acquire_seqcst( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Release`] and [`Ordering::Relaxed`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_release_relaxed( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Release`] and [`Ordering::Acquire`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_release_acquire( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::Release`] and [`Ordering::SeqCst`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_release_seqcst( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::AcqRel`] and [`Ordering::Relaxed`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_acqrel_relaxed( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::AcqRel`] and [`Ordering::Acquire`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_acqrel_acquire( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::AcqRel`] and [`Ordering::SeqCst`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_acqrel_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::SeqCst`] and [`Ordering::Relaxed`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_seqcst_relaxed( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::SeqCst`] and [`Ordering::Acquire`] as the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_seqcst_acquire( + _dst: *mut T, + _old: T, + _src: T, +) -> (T, bool) { + unreachable!() +} +/// Stores a value if the current value is the same as the `old` value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `compare_exchange_weak` method by passing +/// [`Ordering::SeqCst`] as both the success and failure parameters. +/// For example, [`AtomicBool::compare_exchange_weak`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_cxchgweak_seqcst_seqcst(_dst: *mut T, _old: T, _src: T) -> (T, bool) { + unreachable!() +} - /// Loads the current value of the pointer. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `load` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`]. - #[rustc_nounwind] - pub fn atomic_load_seqcst(src: *const T) -> T; - /// Loads the current value of the pointer. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `load` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`]. - #[rustc_nounwind] - pub fn atomic_load_acquire(src: *const T) -> T; - /// Loads the current value of the pointer. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `load` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`]. - #[rustc_nounwind] - pub fn atomic_load_relaxed(src: *const T) -> T; - /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model! - /// In terms of the Rust Abstract Machine, this operation is equivalent to `src.read()`, - /// i.e., it performs a non-atomic read. - #[rustc_nounwind] - pub fn atomic_load_unordered(src: *const T) -> T; +/// Loads the current value of the pointer. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `load` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::load`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_load_seqcst(_src: *const T) -> T { + unreachable!() +} +/// Loads the current value of the pointer. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `load` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::load`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_load_acquire(_src: *const T) -> T { + unreachable!() +} +/// Loads the current value of the pointer. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `load` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::load`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_load_relaxed(_src: *const T) -> T { + unreachable!() +} +/// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model! +/// In terms of the Rust Abstract Machine, this operation is equivalent to `src.read()`, +/// i.e., it performs a non-atomic read. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_load_unordered(_src: *const T) -> T { + unreachable!() +} - /// Stores the value at the specified memory location. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `store` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`]. - #[rustc_nounwind] - pub fn atomic_store_seqcst(dst: *mut T, val: T); - /// Stores the value at the specified memory location. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `store` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`]. - #[rustc_nounwind] - pub fn atomic_store_release(dst: *mut T, val: T); - /// Stores the value at the specified memory location. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `store` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`]. - #[rustc_nounwind] - pub fn atomic_store_relaxed(dst: *mut T, val: T); - /// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model! - /// In terms of the Rust Abstract Machine, this operation is equivalent to `dst.write(val)`, - /// i.e., it performs a non-atomic write. - #[rustc_nounwind] - pub fn atomic_store_unordered(dst: *mut T, val: T); +/// Stores the value at the specified memory location. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `store` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::store`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_store_seqcst(_dst: *mut T, _val: T) { + unreachable!() +} +/// Stores the value at the specified memory location. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `store` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::store`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_store_release(_dst: *mut T, _val: T) { + unreachable!() +} +/// Stores the value at the specified memory location. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `store` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::store`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_store_relaxed(_dst: *mut T, _val: T) { + unreachable!() +} +/// Do NOT use this intrinsic; "unordered" operations do not exist in our memory model! +/// In terms of the Rust Abstract Machine, this operation is equivalent to `dst.write(val)`, +/// i.e., it performs a non-atomic write. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_store_unordered(_dst: *mut T, _val: T) { + unreachable!() +} - /// Stores the value at the specified memory location, returning the old value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `swap` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`]. - #[rustc_nounwind] - pub fn atomic_xchg_seqcst(dst: *mut T, src: T) -> T; - /// Stores the value at the specified memory location, returning the old value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `swap` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`]. - #[rustc_nounwind] - pub fn atomic_xchg_acquire(dst: *mut T, src: T) -> T; - /// Stores the value at the specified memory location, returning the old value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `swap` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`]. - #[rustc_nounwind] - pub fn atomic_xchg_release(dst: *mut T, src: T) -> T; - /// Stores the value at the specified memory location, returning the old value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `swap` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`]. - #[rustc_nounwind] - pub fn atomic_xchg_acqrel(dst: *mut T, src: T) -> T; - /// Stores the value at the specified memory location, returning the old value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `swap` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`]. - #[rustc_nounwind] - pub fn atomic_xchg_relaxed(dst: *mut T, src: T) -> T; +/// Stores the value at the specified memory location, returning the old value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `swap` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::swap`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xchg_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Stores the value at the specified memory location, returning the old value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `swap` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::swap`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xchg_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Stores the value at the specified memory location, returning the old value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `swap` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::swap`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xchg_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Stores the value at the specified memory location, returning the old value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `swap` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::swap`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xchg_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Stores the value at the specified memory location, returning the old value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `swap` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::swap`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xchg_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Adds to the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_add` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`]. - #[rustc_nounwind] - pub fn atomic_xadd_seqcst(dst: *mut T, src: T) -> T; - /// Adds to the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_add` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`]. - #[rustc_nounwind] - pub fn atomic_xadd_acquire(dst: *mut T, src: T) -> T; - /// Adds to the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_add` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`]. - #[rustc_nounwind] - pub fn atomic_xadd_release(dst: *mut T, src: T) -> T; - /// Adds to the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_add` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`]. - #[rustc_nounwind] - pub fn atomic_xadd_acqrel(dst: *mut T, src: T) -> T; - /// Adds to the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_add` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`]. - #[rustc_nounwind] - pub fn atomic_xadd_relaxed(dst: *mut T, src: T) -> T; +/// Adds to the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_add` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_add`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xadd_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Adds to the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_add` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_add`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xadd_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Adds to the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_add` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_add`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xadd_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Adds to the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_add` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_add`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xadd_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Adds to the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_add` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_add`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xadd_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Subtract from the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_sub` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. - #[rustc_nounwind] - pub fn atomic_xsub_seqcst(dst: *mut T, src: T) -> T; - /// Subtract from the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_sub` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. - #[rustc_nounwind] - pub fn atomic_xsub_acquire(dst: *mut T, src: T) -> T; - /// Subtract from the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_sub` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. - #[rustc_nounwind] - pub fn atomic_xsub_release(dst: *mut T, src: T) -> T; - /// Subtract from the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_sub` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. - #[rustc_nounwind] - pub fn atomic_xsub_acqrel(dst: *mut T, src: T) -> T; - /// Subtract from the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_sub` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. - #[rustc_nounwind] - pub fn atomic_xsub_relaxed(dst: *mut T, src: T) -> T; +/// Subtract from the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_sub` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xsub_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Subtract from the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_sub` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xsub_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Subtract from the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_sub` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xsub_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Subtract from the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_sub` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xsub_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Subtract from the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_sub` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicIsize::fetch_sub`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xsub_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Bitwise and with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_and` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`]. - #[rustc_nounwind] - pub fn atomic_and_seqcst(dst: *mut T, src: T) -> T; - /// Bitwise and with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_and` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`]. - #[rustc_nounwind] - pub fn atomic_and_acquire(dst: *mut T, src: T) -> T; - /// Bitwise and with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_and` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`]. - #[rustc_nounwind] - pub fn atomic_and_release(dst: *mut T, src: T) -> T; - /// Bitwise and with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_and` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`]. - #[rustc_nounwind] - pub fn atomic_and_acqrel(dst: *mut T, src: T) -> T; - /// Bitwise and with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_and` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`]. - #[rustc_nounwind] - pub fn atomic_and_relaxed(dst: *mut T, src: T) -> T; +/// Bitwise and with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_and` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_and`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_and_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise and with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_and` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_and`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_and_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise and with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_and` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_and`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_and_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise and with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_and` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_and`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_and_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise and with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_and` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_and`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_and_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Bitwise nand with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`AtomicBool`] type via the `fetch_nand` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`]. - #[rustc_nounwind] - pub fn atomic_nand_seqcst(dst: *mut T, src: T) -> T; - /// Bitwise nand with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`AtomicBool`] type via the `fetch_nand` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`]. - #[rustc_nounwind] - pub fn atomic_nand_acquire(dst: *mut T, src: T) -> T; - /// Bitwise nand with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`AtomicBool`] type via the `fetch_nand` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`]. - #[rustc_nounwind] - pub fn atomic_nand_release(dst: *mut T, src: T) -> T; - /// Bitwise nand with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`AtomicBool`] type via the `fetch_nand` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`]. - #[rustc_nounwind] - pub fn atomic_nand_acqrel(dst: *mut T, src: T) -> T; - /// Bitwise nand with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`AtomicBool`] type via the `fetch_nand` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`]. - #[rustc_nounwind] - pub fn atomic_nand_relaxed(dst: *mut T, src: T) -> T; +/// Bitwise nand with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`AtomicBool`] type via the `fetch_nand` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_nand`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_nand_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise nand with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`AtomicBool`] type via the `fetch_nand` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_nand`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_nand_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise nand with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`AtomicBool`] type via the `fetch_nand` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_nand`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_nand_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise nand with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`AtomicBool`] type via the `fetch_nand` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_nand`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_nand_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise nand with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`AtomicBool`] type via the `fetch_nand` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_nand`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_nand_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Bitwise or with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_or` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`]. - #[rustc_nounwind] - pub fn atomic_or_seqcst(dst: *mut T, src: T) -> T; - /// Bitwise or with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_or` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`]. - #[rustc_nounwind] - pub fn atomic_or_acquire(dst: *mut T, src: T) -> T; - /// Bitwise or with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_or` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`]. - #[rustc_nounwind] - pub fn atomic_or_release(dst: *mut T, src: T) -> T; - /// Bitwise or with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_or` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`]. - #[rustc_nounwind] - pub fn atomic_or_acqrel(dst: *mut T, src: T) -> T; - /// Bitwise or with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_or` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`]. - #[rustc_nounwind] - pub fn atomic_or_relaxed(dst: *mut T, src: T) -> T; +/// Bitwise or with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_or` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_or`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_or_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise or with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_or` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_or`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_or_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise or with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_or` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_or`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_or_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise or with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_or` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_or`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_or_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise or with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_or` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_or`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_or_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Bitwise xor with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_xor` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`]. - #[rustc_nounwind] - pub fn atomic_xor_seqcst(dst: *mut T, src: T) -> T; - /// Bitwise xor with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_xor` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`]. - #[rustc_nounwind] - pub fn atomic_xor_acquire(dst: *mut T, src: T) -> T; - /// Bitwise xor with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_xor` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`]. - #[rustc_nounwind] - pub fn atomic_xor_release(dst: *mut T, src: T) -> T; - /// Bitwise xor with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_xor` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`]. - #[rustc_nounwind] - pub fn atomic_xor_acqrel(dst: *mut T, src: T) -> T; - /// Bitwise xor with the current value, returning the previous value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] types via the `fetch_xor` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`]. - #[rustc_nounwind] - pub fn atomic_xor_relaxed(dst: *mut T, src: T) -> T; +/// Bitwise xor with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_xor` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicBool::fetch_xor`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xor_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise xor with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_xor` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicBool::fetch_xor`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xor_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise xor with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_xor` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicBool::fetch_xor`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xor_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise xor with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_xor` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicBool::fetch_xor`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xor_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Bitwise xor with the current value, returning the previous value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] types via the `fetch_xor` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicBool::fetch_xor`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_xor_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Maximum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_max` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_max_seqcst(dst: *mut T, src: T) -> T; - /// Maximum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_max` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_max_acquire(dst: *mut T, src: T) -> T; - /// Maximum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_max` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_max_release(dst: *mut T, src: T) -> T; - /// Maximum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_max` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_max_acqrel(dst: *mut T, src: T) -> T; - /// Maximum with the current value. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_max` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_max_relaxed(dst: *mut T, src: T) -> T; +/// Maximum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_max` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_max_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Maximum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_max` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_max_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Maximum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_max` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_max_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Maximum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_max` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_max_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Maximum with the current value. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_max` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_max_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Minimum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_min` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_min_seqcst(dst: *mut T, src: T) -> T; - /// Minimum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_min` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_min_acquire(dst: *mut T, src: T) -> T; - /// Minimum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_min` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_min_release(dst: *mut T, src: T) -> T; - /// Minimum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_min` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_min_acqrel(dst: *mut T, src: T) -> T; - /// Minimum with the current value using a signed comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] signed integer types via the `fetch_min` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_min_relaxed(dst: *mut T, src: T) -> T; +/// Minimum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_min` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicI32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_min_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Minimum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_min` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicI32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_min_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Minimum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_min` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicI32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_min_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Minimum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_min` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicI32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_min_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Minimum with the current value using a signed comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] signed integer types via the `fetch_min` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicI32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_min_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Minimum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_min` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_umin_seqcst(dst: *mut T, src: T) -> T; - /// Minimum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_min` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_umin_acquire(dst: *mut T, src: T) -> T; - /// Minimum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_min` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_umin_release(dst: *mut T, src: T) -> T; - /// Minimum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_min` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_umin_acqrel(dst: *mut T, src: T) -> T; - /// Minimum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_min` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`]. - #[rustc_nounwind] - pub fn atomic_umin_relaxed(dst: *mut T, src: T) -> T; +/// Minimum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_min` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umin_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Minimum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_min` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umin_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Minimum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_min` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umin_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Minimum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_min` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umin_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Minimum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_min` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_min`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umin_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// Maximum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_max` method by passing - /// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_umax_seqcst(dst: *mut T, src: T) -> T; - /// Maximum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_max` method by passing - /// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_umax_acquire(dst: *mut T, src: T) -> T; - /// Maximum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_max` method by passing - /// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_umax_release(dst: *mut T, src: T) -> T; - /// Maximum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_max` method by passing - /// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_umax_acqrel(dst: *mut T, src: T) -> T; - /// Maximum with the current value using an unsigned comparison. - /// - /// The stabilized version of this intrinsic is available on the - /// [`atomic`] unsigned integer types via the `fetch_max` method by passing - /// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`]. - #[rustc_nounwind] - pub fn atomic_umax_relaxed(dst: *mut T, src: T) -> T; +/// Maximum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_max` method by passing +/// [`Ordering::SeqCst`] as the `order`. For example, [`AtomicU32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umax_seqcst(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Maximum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_max` method by passing +/// [`Ordering::Acquire`] as the `order`. For example, [`AtomicU32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umax_acquire(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Maximum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_max` method by passing +/// [`Ordering::Release`] as the `order`. For example, [`AtomicU32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umax_release(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Maximum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_max` method by passing +/// [`Ordering::AcqRel`] as the `order`. For example, [`AtomicU32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umax_acqrel(_dst: *mut T, _src: T) -> T { + unreachable!() +} +/// Maximum with the current value using an unsigned comparison. +/// +/// The stabilized version of this intrinsic is available on the +/// [`atomic`] unsigned integer types via the `fetch_max` method by passing +/// [`Ordering::Relaxed`] as the `order`. For example, [`AtomicU32::fetch_max`]. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_umax_relaxed(_dst: *mut T, _src: T) -> T { + unreachable!() +} - /// An atomic fence. - /// - /// The stabilized version of this intrinsic is available in - /// [`atomic::fence`] by passing [`Ordering::SeqCst`] - /// as the `order`. - #[rustc_nounwind] - pub fn atomic_fence_seqcst(); - /// An atomic fence. - /// - /// The stabilized version of this intrinsic is available in - /// [`atomic::fence`] by passing [`Ordering::Acquire`] - /// as the `order`. - #[rustc_nounwind] - pub fn atomic_fence_acquire(); - /// An atomic fence. - /// - /// The stabilized version of this intrinsic is available in - /// [`atomic::fence`] by passing [`Ordering::Release`] - /// as the `order`. - #[rustc_nounwind] - pub fn atomic_fence_release(); - /// An atomic fence. - /// - /// The stabilized version of this intrinsic is available in - /// [`atomic::fence`] by passing [`Ordering::AcqRel`] - /// as the `order`. - #[rustc_nounwind] - pub fn atomic_fence_acqrel(); +/// An atomic fence. +/// +/// The stabilized version of this intrinsic is available in +/// [`atomic::fence`] by passing [`Ordering::SeqCst`] +/// as the `order`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_fence_seqcst() { + unreachable!() +} +/// An atomic fence. +/// +/// The stabilized version of this intrinsic is available in +/// [`atomic::fence`] by passing [`Ordering::Acquire`] +/// as the `order`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_fence_acquire() { + unreachable!() +} +/// An atomic fence. +/// +/// The stabilized version of this intrinsic is available in +/// [`atomic::fence`] by passing [`Ordering::Release`] +/// as the `order`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_fence_release() { + unreachable!() +} +/// An atomic fence. +/// +/// The stabilized version of this intrinsic is available in +/// [`atomic::fence`] by passing [`Ordering::AcqRel`] +/// as the `order`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_fence_acqrel() { + unreachable!() +} - /// A compiler-only memory barrier. - /// - /// Memory accesses will never be reordered across this barrier by the - /// compiler, but no instructions will be emitted for it. This is - /// appropriate for operations on the same thread that may be preempted, - /// such as when interacting with signal handlers. - /// - /// The stabilized version of this intrinsic is available in - /// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`] - /// as the `order`. - #[rustc_nounwind] - pub fn atomic_singlethreadfence_seqcst(); - /// A compiler-only memory barrier. - /// - /// Memory accesses will never be reordered across this barrier by the - /// compiler, but no instructions will be emitted for it. This is - /// appropriate for operations on the same thread that may be preempted, - /// such as when interacting with signal handlers. - /// - /// The stabilized version of this intrinsic is available in - /// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`] - /// as the `order`. - #[rustc_nounwind] - pub fn atomic_singlethreadfence_acquire(); - /// A compiler-only memory barrier. - /// - /// Memory accesses will never be reordered across this barrier by the - /// compiler, but no instructions will be emitted for it. This is - /// appropriate for operations on the same thread that may be preempted, - /// such as when interacting with signal handlers. - /// - /// The stabilized version of this intrinsic is available in - /// [`atomic::compiler_fence`] by passing [`Ordering::Release`] - /// as the `order`. - #[rustc_nounwind] - pub fn atomic_singlethreadfence_release(); - /// A compiler-only memory barrier. - /// - /// Memory accesses will never be reordered across this barrier by the - /// compiler, but no instructions will be emitted for it. This is - /// appropriate for operations on the same thread that may be preempted, - /// such as when interacting with signal handlers. - /// - /// The stabilized version of this intrinsic is available in - /// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`] - /// as the `order`. - #[rustc_nounwind] - pub fn atomic_singlethreadfence_acqrel(); +/// A compiler-only memory barrier. +/// +/// Memory accesses will never be reordered across this barrier by the +/// compiler, but no instructions will be emitted for it. This is +/// appropriate for operations on the same thread that may be preempted, +/// such as when interacting with signal handlers. +/// +/// The stabilized version of this intrinsic is available in +/// [`atomic::compiler_fence`] by passing [`Ordering::SeqCst`] +/// as the `order`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_singlethreadfence_seqcst() { + unreachable!() +} +/// A compiler-only memory barrier. +/// +/// Memory accesses will never be reordered across this barrier by the +/// compiler, but no instructions will be emitted for it. This is +/// appropriate for operations on the same thread that may be preempted, +/// such as when interacting with signal handlers. +/// +/// The stabilized version of this intrinsic is available in +/// [`atomic::compiler_fence`] by passing [`Ordering::Acquire`] +/// as the `order`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_singlethreadfence_acquire() { + unreachable!() +} +/// A compiler-only memory barrier. +/// +/// Memory accesses will never be reordered across this barrier by the +/// compiler, but no instructions will be emitted for it. This is +/// appropriate for operations on the same thread that may be preempted, +/// such as when interacting with signal handlers. +/// +/// The stabilized version of this intrinsic is available in +/// [`atomic::compiler_fence`] by passing [`Ordering::Release`] +/// as the `order`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_singlethreadfence_release() { + unreachable!() +} +/// A compiler-only memory barrier. +/// +/// Memory accesses will never be reordered across this barrier by the +/// compiler, but no instructions will be emitted for it. This is +/// appropriate for operations on the same thread that may be preempted, +/// such as when interacting with signal handlers. +/// +/// The stabilized version of this intrinsic is available in +/// [`atomic::compiler_fence`] by passing [`Ordering::AcqRel`] +/// as the `order`. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn atomic_singlethreadfence_acqrel() { + unreachable!() +} - /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction - /// if supported; otherwise, it is a no-op. - /// Prefetches have no effect on the behavior of the program but can change its performance - /// characteristics. - /// - /// The `locality` argument must be a constant integer and is a temporal locality specifier - /// ranging from (0) - no locality, to (3) - extremely local keep in cache. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn prefetch_read_data(data: *const T, locality: i32); - /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction - /// if supported; otherwise, it is a no-op. - /// Prefetches have no effect on the behavior of the program but can change its performance - /// characteristics. - /// - /// The `locality` argument must be a constant integer and is a temporal locality specifier - /// ranging from (0) - no locality, to (3) - extremely local keep in cache. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn prefetch_write_data(data: *const T, locality: i32); - /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction - /// if supported; otherwise, it is a no-op. - /// Prefetches have no effect on the behavior of the program but can change its performance - /// characteristics. - /// - /// The `locality` argument must be a constant integer and is a temporal locality specifier - /// ranging from (0) - no locality, to (3) - extremely local keep in cache. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn prefetch_read_instruction(data: *const T, locality: i32); - /// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction - /// if supported; otherwise, it is a no-op. - /// Prefetches have no effect on the behavior of the program but can change its performance - /// characteristics. - /// - /// The `locality` argument must be a constant integer and is a temporal locality specifier - /// ranging from (0) - no locality, to (3) - extremely local keep in cache. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn prefetch_write_instruction(data: *const T, locality: i32); +/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction +/// if supported; otherwise, it is a no-op. +/// Prefetches have no effect on the behavior of the program but can change its performance +/// characteristics. +/// +/// The `locality` argument must be a constant integer and is a temporal locality specifier +/// ranging from (0) - no locality, to (3) - extremely local keep in cache. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn prefetch_read_data(_data: *const T, _locality: i32) { + unreachable!() +} +/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction +/// if supported; otherwise, it is a no-op. +/// Prefetches have no effect on the behavior of the program but can change its performance +/// characteristics. +/// +/// The `locality` argument must be a constant integer and is a temporal locality specifier +/// ranging from (0) - no locality, to (3) - extremely local keep in cache. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn prefetch_write_data(_data: *const T, _locality: i32) { + unreachable!() +} +/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction +/// if supported; otherwise, it is a no-op. +/// Prefetches have no effect on the behavior of the program but can change its performance +/// characteristics. +/// +/// The `locality` argument must be a constant integer and is a temporal locality specifier +/// ranging from (0) - no locality, to (3) - extremely local keep in cache. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn prefetch_read_instruction(_data: *const T, _locality: i32) { + unreachable!() +} +/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction +/// if supported; otherwise, it is a no-op. +/// Prefetches have no effect on the behavior of the program but can change its performance +/// characteristics. +/// +/// The `locality` argument must be a constant integer and is a temporal locality specifier +/// ranging from (0) - no locality, to (3) - extremely local keep in cache. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn prefetch_write_instruction(_data: *const T, _locality: i32) { + unreachable!() +} - /// Executes a breakpoint trap, for inspection by a debugger. - /// - /// This intrinsic does not have a stable counterpart. - #[rustc_nounwind] - pub fn breakpoint(); +/// Executes a breakpoint trap, for inspection by a debugger. +/// +/// This intrinsic does not have a stable counterpart. +#[rustc_intrinsic] +#[rustc_intrinsic_must_be_overridden] +#[rustc_nounwind] +pub unsafe fn breakpoint() { + unreachable!() } /// Magic intrinsic that derives its meaning from attributes diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs index 87bfd0d256634..6dca740684537 100644 --- a/library/core/src/num/dec2flt/mod.rs +++ b/library/core/src/num/dec2flt/mod.rs @@ -58,7 +58,7 @@ //! //! There are unit tests but they are woefully inadequate at ensuring correctness, they only cover //! a small percentage of possible errors. Far more extensive tests are located in the directory -//! `src/etc/test-float-parse` as a Python script. +//! `src/etc/test-float-parse` as a Rust program. //! //! A note on integer overflow: Many parts of this file perform arithmetic with the decimal //! exponent `e`. Primarily, we shift the decimal point around: Before the first decimal digit, diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 46e86c306fb1a..c3862d994986a 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -285,17 +285,6 @@ impl f128 { self != self } - // FIXME(#50145): `abs` is publicly unavailable in core due to - // concerns about portability, so this implementation is for - // private use internally. - #[inline] - pub(crate) const fn abs_private(self) -> f128 { - // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`. - unsafe { - mem::transmute::(mem::transmute::(self) & !Self::SIGN_MASK) - } - } - /// Returns `true` if this value is positive infinity or negative infinity, and /// `false` otherwise. /// @@ -345,10 +334,11 @@ impl f128 { #[inline] #[must_use] #[unstable(feature = "f128", issue = "116909")] + #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < Self::INFINITY + self.abs() < Self::INFINITY } /// Returns `true` if the number is [subnormal]. @@ -836,8 +826,8 @@ impl f128 { const HI: f128 = f128::MAX / 2.; let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let abs_a = a.abs(); + let abs_b = b.abs(); if abs_a <= HI && abs_b <= HI { // Overflow is impossible @@ -1281,4 +1271,100 @@ impl f128 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// #![feature(f128)] + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// let x = 3.5_f128; + /// let y = -3.5_f128; + /// + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); + /// + /// assert!(f128::NAN.abs().is_nan()); + /// # } + /// ``` + #[inline] + #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn abs(self) -> Self { + // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available + // We don't do this now because LLVM has lowering bugs for f128 math. + Self::from_bits(self.to_bits() & !(1 << 127)) + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `INFINITY` + /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` + /// - NaN if the number is NaN + /// + /// # Examples + /// + /// ``` + /// #![feature(f128)] + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// let f = 3.5_f128; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f128::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f128::NAN.signum().is_nan()); + /// # } + /// ``` + #[inline] + #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn signum(self) -> f128 { + if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) } + } + + /// Returns a number composed of the magnitude of `self` and the sign of + /// `sign`. + /// + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. + /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust + /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the + /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. + /// + /// # Examples + /// + /// ``` + /// #![feature(f128)] + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// let f = 3.5_f128; + /// + /// assert_eq!(f.copysign(0.42), 3.5_f128); + /// assert_eq!(f.copysign(-0.42), -3.5_f128); + /// assert_eq!((-f).copysign(0.42), 3.5_f128); + /// assert_eq!((-f).copysign(-0.42), -3.5_f128); + /// + /// assert!(f128::NAN.copysign(1.0).is_nan()); + /// # } + /// ``` + #[inline] + #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn copysign(self, sign: f128) -> f128 { + // SAFETY: this is actually a safe intrinsic + unsafe { intrinsics::copysignf128(self, sign) } + } } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 91a9bb5cbbe1b..ed35316cf8f9c 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -279,15 +279,6 @@ impl f16 { self != self } - // FIXMxE(#50145): `abs` is publicly unavailable in core due to - // concerns about portability, so this implementation is for - // private use internally. - #[inline] - pub(crate) const fn abs_private(self) -> f16 { - // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`. - unsafe { mem::transmute::(mem::transmute::(self) & !Self::SIGN_MASK) } - } - /// Returns `true` if this value is positive infinity or negative infinity, and /// `false` otherwise. /// @@ -335,10 +326,11 @@ impl f16 { #[inline] #[must_use] #[unstable(feature = "f16", issue = "116909")] + #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < Self::INFINITY + self.abs() < Self::INFINITY } /// Returns `true` if the number is [subnormal]. @@ -821,8 +813,8 @@ impl f16 { const HI: f16 = f16::MAX / 2.; let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let abs_a = a.abs(); + let abs_b = b.abs(); if abs_a <= HI && abs_b <= HI { // Overflow is impossible @@ -1256,4 +1248,99 @@ impl f16 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// #![feature(f16)] + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// let x = 3.5_f16; + /// let y = -3.5_f16; + /// + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); + /// + /// assert!(f16::NAN.abs().is_nan()); + /// # } + /// ``` + #[inline] + #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn abs(self) -> Self { + // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available + Self::from_bits(self.to_bits() & !(1 << 15)) + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `INFINITY` + /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` + /// - NaN if the number is NaN + /// + /// # Examples + /// + /// ``` + /// #![feature(f16)] + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// let f = 3.5_f16; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f16::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f16::NAN.signum().is_nan()); + /// # } + /// ``` + #[inline] + #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn signum(self) -> f16 { + if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) } + } + + /// Returns a number composed of the magnitude of `self` and the sign of + /// `sign`. + /// + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. + /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust + /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the + /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. + /// + /// # Examples + /// + /// ``` + /// #![feature(f16)] + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// let f = 3.5_f16; + /// + /// assert_eq!(f.copysign(0.42), 3.5_f16); + /// assert_eq!(f.copysign(-0.42), -3.5_f16); + /// assert_eq!((-f).copysign(0.42), 3.5_f16); + /// assert_eq!((-f).copysign(-0.42), -3.5_f16); + /// + /// assert!(f16::NAN.copysign(1.0).is_nan()); + /// # } + /// ``` + #[inline] + #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn copysign(self, sign: f16) -> f16 { + // SAFETY: this is actually a safe intrinsic + unsafe { intrinsics::copysignf16(self, sign) } + } } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 20ece883da60b..ae9e69f56fba5 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -525,15 +525,6 @@ impl f32 { self != self } - // FIXME(#50145): `abs` is publicly unavailable in core due to - // concerns about portability, so this implementation is for - // private use internally. - #[inline] - pub(crate) const fn abs_private(self) -> f32 { - // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`. - unsafe { mem::transmute::(mem::transmute::(self) & !Self::SIGN_MASK) } - } - /// Returns `true` if this value is positive infinity or negative infinity, and /// `false` otherwise. /// @@ -578,10 +569,11 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] + #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < Self::INFINITY + self.abs() < Self::INFINITY } /// Returns `true` if the number is [subnormal]. @@ -1019,8 +1011,8 @@ impl f32 { const HI: f32 = f32::MAX / 2.; let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let abs_a = a.abs(); + let abs_b = b.abs(); if abs_a <= HI && abs_b <= HI { // Overflow is impossible @@ -1424,4 +1416,87 @@ impl f32 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// let x = 3.5_f32; + /// let y = -3.5_f32; + /// + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); + /// + /// assert!(f32::NAN.abs().is_nan()); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn abs(self) -> f32 { + // SAFETY: this is actually a safe intrinsic + unsafe { intrinsics::fabsf32(self) } + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `INFINITY` + /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` + /// - NaN if the number is NaN + /// + /// # Examples + /// + /// ``` + /// let f = 3.5_f32; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f32::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f32::NAN.signum().is_nan()); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn signum(self) -> f32 { + if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } + } + + /// Returns a number composed of the magnitude of `self` and the sign of + /// `sign`. + /// + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. + /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust + /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the + /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. + /// + /// # Examples + /// + /// ``` + /// let f = 3.5_f32; + /// + /// assert_eq!(f.copysign(0.42), 3.5_f32); + /// assert_eq!(f.copysign(-0.42), -3.5_f32); + /// assert_eq!((-f).copysign(0.42), 3.5_f32); + /// assert_eq!((-f).copysign(-0.42), -3.5_f32); + /// + /// assert!(f32::NAN.copysign(1.0).is_nan()); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[inline] + #[stable(feature = "copysign", since = "1.35.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + pub const fn copysign(self, sign: f32) -> f32 { + // SAFETY: this is actually a safe intrinsic + unsafe { intrinsics::copysignf32(self, sign) } + } } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 5640e71788b85..98dcbffd3b49e 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -524,15 +524,6 @@ impl f64 { self != self } - // FIXME(#50145): `abs` is publicly unavailable in core due to - // concerns about portability, so this implementation is for - // private use internally. - #[inline] - pub(crate) const fn abs_private(self) -> f64 { - // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`. - unsafe { mem::transmute::(mem::transmute::(self) & !Self::SIGN_MASK) } - } - /// Returns `true` if this value is positive infinity or negative infinity, and /// `false` otherwise. /// @@ -577,10 +568,11 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] + #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < Self::INFINITY + self.abs() < Self::INFINITY } /// Returns `true` if the number is [subnormal]. @@ -1022,8 +1014,8 @@ impl f64 { const HI: f64 = f64::MAX / 2.; let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let abs_a = a.abs(); + let abs_b = b.abs(); if abs_a <= HI && abs_b <= HI { // Overflow is impossible @@ -1424,4 +1416,87 @@ impl f64 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// let x = 3.5_f64; + /// let y = -3.5_f64; + /// + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); + /// + /// assert!(f64::NAN.abs().is_nan()); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn abs(self) -> f64 { + // SAFETY: this is actually a safe intrinsic + unsafe { intrinsics::fabsf64(self) } + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `1.0` if the number is positive, `+0.0` or `INFINITY` + /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` + /// - NaN if the number is NaN + /// + /// # Examples + /// + /// ``` + /// let f = 3.5_f64; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f64::NAN.signum().is_nan()); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn signum(self) -> f64 { + if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } + } + + /// Returns a number composed of the magnitude of `self` and the sign of + /// `sign`. + /// + /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. + /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust + /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the + /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. + /// + /// # Examples + /// + /// ``` + /// let f = 3.5_f64; + /// + /// assert_eq!(f.copysign(0.42), 3.5_f64); + /// assert_eq!(f.copysign(-0.42), -3.5_f64); + /// assert_eq!((-f).copysign(0.42), 3.5_f64); + /// assert_eq!((-f).copysign(-0.42), -3.5_f64); + /// + /// assert!(f64::NAN.copysign(1.0).is_nan()); + /// ``` + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "copysign", since = "1.35.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn copysign(self, sign: f64) -> f64 { + // SAFETY: this is actually a safe intrinsic + unsafe { intrinsics::copysignf64(self, sign) } + } } diff --git a/library/core/tests/clone.rs b/library/core/tests/clone.rs index 71a328733b7c4..054b1d3d4986c 100644 --- a/library/core/tests/clone.rs +++ b/library/core/tests/clone.rs @@ -28,7 +28,7 @@ fn test_clone_to_uninit_slice_success() { let mut storage: MaybeUninit<[String; 3]> = MaybeUninit::uninit(); let b: [String; 3] = unsafe { - a[..].clone_to_uninit(storage.as_mut_ptr() as *mut [String]); + a[..].clone_to_uninit(storage.as_mut_ptr().cast()); storage.assume_init() }; @@ -70,7 +70,7 @@ fn test_clone_to_uninit_slice_drops_on_panic() { let mut storage: MaybeUninit<[CountsDropsAndPanics; 3]> = MaybeUninit::uninit(); // This should panic halfway through unsafe { - a[..].clone_to_uninit(storage.as_mut_ptr() as *mut [CountsDropsAndPanics]); + a[..].clone_to_uninit(storage.as_mut_ptr().cast()); } }) .unwrap_err(); @@ -89,13 +89,13 @@ fn test_clone_to_uninit_str() { let a = "hello"; let mut storage: MaybeUninit<[u8; 5]> = MaybeUninit::uninit(); - unsafe { a.clone_to_uninit(storage.as_mut_ptr() as *mut [u8] as *mut str) }; + unsafe { a.clone_to_uninit(storage.as_mut_ptr().cast()) }; assert_eq!(a.as_bytes(), unsafe { storage.assume_init() }.as_slice()); let mut b: Box = "world".into(); assert_eq!(a.len(), b.len()); assert_ne!(a, &*b); - unsafe { a.clone_to_uninit(ptr::from_mut::(&mut b)) }; + unsafe { a.clone_to_uninit(ptr::from_mut::(&mut b).cast()) }; assert_eq!(a, &*b); } @@ -104,13 +104,13 @@ fn test_clone_to_uninit_cstr() { let a = c"hello"; let mut storage: MaybeUninit<[u8; 6]> = MaybeUninit::uninit(); - unsafe { a.clone_to_uninit(storage.as_mut_ptr() as *mut [u8] as *mut CStr) }; + unsafe { a.clone_to_uninit(storage.as_mut_ptr().cast()) }; assert_eq!(a.to_bytes_with_nul(), unsafe { storage.assume_init() }.as_slice()); let mut b: Box = c"world".into(); assert_eq!(a.count_bytes(), b.count_bytes()); assert_ne!(a, &*b); - unsafe { a.clone_to_uninit(ptr::from_mut::(&mut b)) }; + unsafe { a.clone_to_uninit(ptr::from_mut::(&mut b).cast()) }; assert_eq!(a, &*b); } diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index 229f979b5b10b..e93e915159e40 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -188,104 +188,6 @@ impl f128 { self - self.trunc() } - /// Computes the absolute value of `self`. - /// - /// This function always returns the precise result. - /// - /// # Examples - /// - /// ``` - /// #![feature(f128)] - /// # #[cfg(reliable_f128)] { - /// - /// let x = 3.5_f128; - /// let y = -3.5_f128; - /// - /// assert_eq!(x.abs(), x); - /// assert_eq!(y.abs(), -y); - /// - /// assert!(f128::NAN.abs().is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn abs(self) -> Self { - // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available - // We don't do this now because LLVM has lowering bugs for f128 math. - Self::from_bits(self.to_bits() & !(1 << 127)) - } - - /// Returns a number that represents the sign of `self`. - /// - /// - `1.0` if the number is positive, `+0.0` or `INFINITY` - /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - NaN if the number is NaN - /// - /// # Examples - /// - /// ``` - /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { - /// - /// let f = 3.5_f128; - /// - /// assert_eq!(f.signum(), 1.0); - /// assert_eq!(f128::NEG_INFINITY.signum(), -1.0); - /// - /// assert!(f128::NAN.signum().is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn signum(self) -> f128 { - if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) } - } - - /// Returns a number composed of the magnitude of `self` and the sign of - /// `sign`. - /// - /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. - /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is - /// returned. - /// - /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note - /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust - /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the - /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable - /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more - /// info. - /// - /// # Examples - /// - /// ``` - /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { - /// - /// let f = 3.5_f128; - /// - /// assert_eq!(f.copysign(0.42), 3.5_f128); - /// assert_eq!(f.copysign(-0.42), -3.5_f128); - /// assert_eq!((-f).copysign(0.42), 3.5_f128); - /// assert_eq!((-f).copysign(-0.42), -3.5_f128); - /// - /// assert!(f128::NAN.copysign(1.0).is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn copysign(self, sign: f128) -> f128 { - unsafe { intrinsics::copysignf128(self, sign) } - } - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error, yielding a more accurate result than an unfused multiply-add. /// diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index bed21cda1cd91..5b7fcaa28e064 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -188,103 +188,6 @@ impl f16 { self - self.trunc() } - /// Computes the absolute value of `self`. - /// - /// This function always returns the precise result. - /// - /// # Examples - /// - /// ``` - /// #![feature(f16)] - /// # #[cfg(reliable_f16)] { - /// - /// let x = 3.5_f16; - /// let y = -3.5_f16; - /// - /// assert_eq!(x.abs(), x); - /// assert_eq!(y.abs(), -y); - /// - /// assert!(f16::NAN.abs().is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn abs(self) -> Self { - // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available - Self::from_bits(self.to_bits() & !(1 << 15)) - } - - /// Returns a number that represents the sign of `self`. - /// - /// - `1.0` if the number is positive, `+0.0` or `INFINITY` - /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - NaN if the number is NaN - /// - /// # Examples - /// - /// ``` - /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { - /// - /// let f = 3.5_f16; - /// - /// assert_eq!(f.signum(), 1.0); - /// assert_eq!(f16::NEG_INFINITY.signum(), -1.0); - /// - /// assert!(f16::NAN.signum().is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn signum(self) -> f16 { - if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) } - } - - /// Returns a number composed of the magnitude of `self` and the sign of - /// `sign`. - /// - /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. - /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is - /// returned. - /// - /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note - /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust - /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the - /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable - /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more - /// info. - /// - /// # Examples - /// - /// ``` - /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { - /// - /// let f = 3.5_f16; - /// - /// assert_eq!(f.copysign(0.42), 3.5_f16); - /// assert_eq!(f.copysign(-0.42), -3.5_f16); - /// assert_eq!((-f).copysign(0.42), 3.5_f16); - /// assert_eq!((-f).copysign(-0.42), -3.5_f16); - /// - /// assert!(f16::NAN.copysign(1.0).is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn copysign(self, sign: f16) -> f16 { - unsafe { intrinsics::copysignf16(self, sign) } - } - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error, yielding a more accurate result than an unfused multiply-add. /// diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 30cf4e1f756e0..7cb285bbff5f7 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -176,90 +176,6 @@ impl f32 { self - self.trunc() } - /// Computes the absolute value of `self`. - /// - /// This function always returns the precise result. - /// - /// # Examples - /// - /// ``` - /// let x = 3.5_f32; - /// let y = -3.5_f32; - /// - /// assert_eq!(x.abs(), x); - /// assert_eq!(y.abs(), -y); - /// - /// assert!(f32::NAN.abs().is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn abs(self) -> f32 { - unsafe { intrinsics::fabsf32(self) } - } - - /// Returns a number that represents the sign of `self`. - /// - /// - `1.0` if the number is positive, `+0.0` or `INFINITY` - /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - NaN if the number is NaN - /// - /// # Examples - /// - /// ``` - /// let f = 3.5_f32; - /// - /// assert_eq!(f.signum(), 1.0); - /// assert_eq!(f32::NEG_INFINITY.signum(), -1.0); - /// - /// assert!(f32::NAN.signum().is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn signum(self) -> f32 { - if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } - } - - /// Returns a number composed of the magnitude of `self` and the sign of - /// `sign`. - /// - /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. - /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is - /// returned. - /// - /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note - /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust - /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the - /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable - /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more - /// info. - /// - /// # Examples - /// - /// ``` - /// let f = 3.5_f32; - /// - /// assert_eq!(f.copysign(0.42), 3.5_f32); - /// assert_eq!(f.copysign(-0.42), -3.5_f32); - /// assert_eq!((-f).copysign(0.42), 3.5_f32); - /// assert_eq!((-f).copysign(-0.42), -3.5_f32); - /// - /// assert!(f32::NAN.copysign(1.0).is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[inline] - #[stable(feature = "copysign", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - pub const fn copysign(self, sign: f32) -> f32 { - unsafe { intrinsics::copysignf32(self, sign) } - } - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error, yielding a more accurate result than an unfused multiply-add. /// diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 51d5476b372d2..47163c272de32 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -176,90 +176,6 @@ impl f64 { self - self.trunc() } - /// Computes the absolute value of `self`. - /// - /// This function always returns the precise result. - /// - /// # Examples - /// - /// ``` - /// let x = 3.5_f64; - /// let y = -3.5_f64; - /// - /// assert_eq!(x.abs(), x); - /// assert_eq!(y.abs(), -y); - /// - /// assert!(f64::NAN.abs().is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn abs(self) -> f64 { - unsafe { intrinsics::fabsf64(self) } - } - - /// Returns a number that represents the sign of `self`. - /// - /// - `1.0` if the number is positive, `+0.0` or `INFINITY` - /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - NaN if the number is NaN - /// - /// # Examples - /// - /// ``` - /// let f = 3.5_f64; - /// - /// assert_eq!(f.signum(), 1.0); - /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0); - /// - /// assert!(f64::NAN.signum().is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn signum(self) -> f64 { - if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } - } - - /// Returns a number composed of the magnitude of `self` and the sign of - /// `sign`. - /// - /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise equal to `-self`. - /// If `self` is a NaN, then a NaN with the same payload as `self` and the sign bit of `sign` is - /// returned. - /// - /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note - /// that IEEE 754 doesn't assign any meaning to the sign bit in case of a NaN, and as Rust - /// doesn't guarantee that the bit pattern of NaNs are conserved over arithmetic operations, the - /// result of `copysign` with `sign` being a NaN might produce an unexpected or non-portable - /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more - /// info. - /// - /// # Examples - /// - /// ``` - /// let f = 3.5_f64; - /// - /// assert_eq!(f.copysign(0.42), 3.5_f64); - /// assert_eq!(f.copysign(-0.42), -3.5_f64); - /// assert_eq!((-f).copysign(0.42), 3.5_f64); - /// assert_eq!((-f).copysign(-0.42), -3.5_f64); - /// - /// assert!(f64::NAN.copysign(1.0).is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "copysign", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn copysign(self, sign: f64) -> f64 { - unsafe { intrinsics::copysignf64(self, sign) } - } - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error, yielding a more accurate result than an unfused multiply-add. /// diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index b19d482feaad0..79dfb47d0c499 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -112,7 +112,7 @@ impl crate::sealed::Sealed for OsString {} /// [conversions]: super#conversions #[cfg_attr(not(test), rustc_diagnostic_item = "OsStr")] #[stable(feature = "rust1", since = "1.0.0")] -// `OsStr::from_inner` current implementation relies +// `OsStr::from_inner` and `impl CloneToUninit for OsStr` current implementation relies // on `OsStr` being layout-compatible with `Slice`. // However, `OsStr` layout is considered an implementation detail and must not be relied upon. #[repr(transparent)] @@ -1278,9 +1278,9 @@ impl Clone for Box { unsafe impl CloneToUninit for OsStr { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { - // SAFETY: we're just a wrapper around a platform-specific Slice - unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) } + unsafe fn clone_to_uninit(&self, dst: *mut u8) { + // SAFETY: we're just a transparent wrapper around a platform-specific Slice + unsafe { self.inner.clone_to_uninit(dst) } } } diff --git a/library/std/src/ffi/os_str/tests.rs b/library/std/src/ffi/os_str/tests.rs index 67147934b4db3..cbec44c862646 100644 --- a/library/std/src/ffi/os_str/tests.rs +++ b/library/std/src/ffi/os_str/tests.rs @@ -294,12 +294,12 @@ fn clone_to_uninit() { let a = OsStr::new("hello.txt"); let mut storage = vec![MaybeUninit::::uninit(); size_of_val::(a)]; - unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()) as *mut OsStr) }; + unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) }; assert_eq!(a.as_encoded_bytes(), unsafe { MaybeUninit::slice_assume_init_ref(&storage) }); let mut b: Box = OsStr::new("world.exe").into(); assert_eq!(size_of_val::(a), size_of_val::(&b)); assert_ne!(a, &*b); - unsafe { a.clone_to_uninit(ptr::from_mut::(&mut b)) }; + unsafe { a.clone_to_uninit(ptr::from_mut::(&mut b).cast()) }; assert_eq!(a, &*b); } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 5662a44d83232..b0291e3aa196f 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -2128,7 +2128,7 @@ impl AsRef for PathBuf { /// ``` #[cfg_attr(not(test), rustc_diagnostic_item = "Path")] #[stable(feature = "rust1", since = "1.0.0")] -// `Path::new` current implementation relies +// `Path::new` and `impl CloneToUninit for Path` current implementation relies // on `Path` being layout-compatible with `OsStr`. // However, `Path` layout is considered an implementation detail and must not be relied upon. #[repr(transparent)] @@ -3170,9 +3170,9 @@ impl Path { unsafe impl CloneToUninit for Path { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { - // SAFETY: Path is just a wrapper around OsStr - unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) } + unsafe fn clone_to_uninit(&self, dst: *mut u8) { + // SAFETY: Path is just a transparent wrapper around OsStr + unsafe { self.inner.clone_to_uninit(dst) } } } diff --git a/library/std/src/path/tests.rs b/library/std/src/path/tests.rs index b75793d2bc990..ff3f7151bb834 100644 --- a/library/std/src/path/tests.rs +++ b/library/std/src/path/tests.rs @@ -2068,7 +2068,7 @@ fn clone_to_uninit() { let a = Path::new("hello.txt"); let mut storage = vec![MaybeUninit::::uninit(); size_of_val::(a)]; - unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()) as *mut Path) }; + unsafe { a.clone_to_uninit(ptr::from_mut::<[_]>(storage.as_mut_slice()).cast()) }; assert_eq!(a.as_os_str().as_encoded_bytes(), unsafe { MaybeUninit::slice_assume_init_ref(&storage) }); @@ -2076,6 +2076,6 @@ fn clone_to_uninit() { let mut b: Box = Path::new("world.exe").into(); assert_eq!(size_of_val::(a), size_of_val::(&b)); assert_ne!(a, &*b); - unsafe { a.clone_to_uninit(ptr::from_mut::(&mut b)) }; + unsafe { a.clone_to_uninit(ptr::from_mut::(&mut b).cast()) }; assert_eq!(a, &*b); } diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index 8e0609fe48c53..5b65d862be102 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -352,8 +352,8 @@ impl Slice { unsafe impl CloneToUninit for Slice { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { - // SAFETY: we're just a wrapper around [u8] - unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) } + unsafe fn clone_to_uninit(&self, dst: *mut u8) { + // SAFETY: we're just a transparent wrapper around [u8] + unsafe { self.inner.clone_to_uninit(dst) } } } diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index b3834388df68a..a4ad5966afe57 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -275,8 +275,8 @@ impl Slice { unsafe impl CloneToUninit for Slice { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { - // SAFETY: we're just a wrapper around Wtf8 - unsafe { self.inner.clone_to_uninit(&raw mut (*dst).inner) } + unsafe fn clone_to_uninit(&self, dst: *mut u8) { + // SAFETY: we're just a transparent wrapper around Wtf8 + unsafe { self.inner.clone_to_uninit(dst) } } } diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 19d4c94f45099..666942bb8a10f 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -1052,8 +1052,8 @@ impl Hash for Wtf8 { unsafe impl CloneToUninit for Wtf8 { #[inline] #[cfg_attr(debug_assertions, track_caller)] - unsafe fn clone_to_uninit(&self, dst: *mut Self) { - // SAFETY: we're just a wrapper around [u8] - unsafe { self.bytes.clone_to_uninit(&raw mut (*dst).bytes) } + unsafe fn clone_to_uninit(&self, dst: *mut u8) { + // SAFETY: we're just a transparent wrapper around [u8] + unsafe { self.bytes.clone_to_uninit(dst) } } } diff --git a/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.rs b/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.rs new file mode 100644 index 0000000000000..346ef64a8a6c1 --- /dev/null +++ b/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.rs @@ -0,0 +1,21 @@ +// Regression test for #132955 checking that we handle anon consts with +// inference variables in their generic arguments correctly. +// +// This arose via diagnostics where we would have some failing goal such +// as `[u8; AnonConst]: PartialEq`, then as part of diagnostics +// we would replace all generic parameters with inference vars which would yield +// a self type of `[u8; AnonConst]` and then attempt to normalize `AnonConst`. + +pub trait T { + type A; + const P: Self::A; + + fn a() { + [0u8; std::mem::size_of::()] == Self::P; + //~^ ERROR: can't compare + //~| ERROR: constant expression depends on a generic parameter + //~| ERROR: constant expression depends on a generic parameter + } +} + +fn main() {} diff --git a/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.stderr b/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.stderr new file mode 100644 index 0000000000000..12de4f1dc3003 --- /dev/null +++ b/tests/ui/const-generics/failing_goal_with_repeat_expr_anon_const.stderr @@ -0,0 +1,31 @@ +error: constant expression depends on a generic parameter + --> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:15 + | +LL | [0u8; std::mem::size_of::()] == Self::P; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error: constant expression depends on a generic parameter + --> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47 + | +LL | [0u8; std::mem::size_of::()] == Self::P; + | ^^ + | + = note: this may fail depending on what value the parameter takes + +error[E0277]: can't compare `[u8; std::mem::size_of::()]` with `::A` + --> $DIR/failing_goal_with_repeat_expr_anon_const.rs:14:47 + | +LL | [0u8; std::mem::size_of::()] == Self::P; + | ^^ no implementation for `[u8; std::mem::size_of::()] == ::A` + | + = help: the trait `PartialEq<::A>` is not implemented for `[u8; std::mem::size_of::()]` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | pub trait T where [u8; std::mem::size_of::()]: PartialEq<::A> { + | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/inline-const/cross_const_control_flow.rs b/tests/ui/inline-const/cross_const_control_flow.rs new file mode 100644 index 0000000000000..109764a1812d2 --- /dev/null +++ b/tests/ui/inline-const/cross_const_control_flow.rs @@ -0,0 +1,46 @@ +//@edition:2021 + +fn foo() { + const { return } + //~^ ERROR: return statement outside of function body +} + +fn labelled_block_break() { + 'a: { const { break 'a } } + //~^ ERROR: `break` outside of a loop or labeled block + //~| ERROR: use of unreachable label +} + +fn loop_break() { + loop { + const { break } + //~^ ERROR: `break` outside of a loop or labeled block + } +} + +fn continue_to_labelled_block() { + 'a: { const { continue 'a } } + //~^ ERROR: `continue` outside of a loop + //~| ERROR: use of unreachable label +} + +fn loop_continue() { + loop { + const { continue } + //~^ ERROR: `continue` outside of a loop + } +} + +async fn await_across_const_block() { + const { async {}.await } + //~^ ERROR: `await` is only allowed inside `async` functions and blocks +} + +fn reference_to_non_constant_in_const_block() { + let x = 1; + const { &x }; + //~^ ERROR: attempt to use a non-constant value in a constant +} + + +fn main() {} diff --git a/tests/ui/inline-const/cross_const_control_flow.stderr b/tests/ui/inline-const/cross_const_control_flow.stderr new file mode 100644 index 0000000000000..ecfa921edd2c6 --- /dev/null +++ b/tests/ui/inline-const/cross_const_control_flow.stderr @@ -0,0 +1,78 @@ +error[E0767]: use of unreachable label `'a` + --> $DIR/cross_const_control_flow.rs:9:25 + | +LL | 'a: { const { break 'a } } + | -- ^^ unreachable label `'a` + | | + | unreachable label defined here + | + = note: labels are unreachable through functions, closures, async blocks and modules + +error[E0767]: use of unreachable label `'a` + --> $DIR/cross_const_control_flow.rs:22:28 + | +LL | 'a: { const { continue 'a } } + | -- ^^ unreachable label `'a` + | | + | unreachable label defined here + | + = note: labels are unreachable through functions, closures, async blocks and modules + +error[E0435]: attempt to use a non-constant value in a constant + --> $DIR/cross_const_control_flow.rs:41:14 + | +LL | const { &x }; + | ^ non-constant value + | +help: consider using `const` instead of `let` + | +LL | const x: /* Type */ = 1; + | ~~~~~ ++++++++++++ + +error[E0728]: `await` is only allowed inside `async` functions and blocks + --> $DIR/cross_const_control_flow.rs:35:22 + | +LL | const { async {}.await } + | -----------^^^^^-- + | | | + | | only allowed inside `async` functions and blocks + | this is not `async` + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/cross_const_control_flow.rs:9:19 + | +LL | 'a: { const { break 'a } } + | ^^^^^^^^ cannot `break` outside of a loop or labeled block + +error[E0268]: `break` outside of a loop or labeled block + --> $DIR/cross_const_control_flow.rs:16:17 + | +LL | const { break } + | ^^^^^ cannot `break` outside of a loop or labeled block + +error[E0268]: `continue` outside of a loop + --> $DIR/cross_const_control_flow.rs:22:19 + | +LL | 'a: { const { continue 'a } } + | ^^^^^^^^^^^ cannot `continue` outside of a loop + +error[E0268]: `continue` outside of a loop + --> $DIR/cross_const_control_flow.rs:29:17 + | +LL | const { continue } + | ^^^^^^^^ cannot `continue` outside of a loop + +error[E0572]: return statement outside of function body + --> $DIR/cross_const_control_flow.rs:4:13 + | +LL | / fn foo() { +LL | | const { return } + | | --^^^^^^-- the return is part of this body... +LL | | +LL | | } + | |_- ...not the enclosing function body + +error: aborting due to 9 previous errors + +Some errors have detailed explanations: E0268, E0435, E0572, E0728, E0767. +For more information about an error, try `rustc --explain E0268`.