diff options
| author | bors <bors@rust-lang.org> | 2024-12-30 23:46:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-12-30 23:46:42 +0000 |
| commit | 4e5fec2f1ea4b1cfecaa14304c9f56de59b344cb (patch) | |
| tree | 1e4e8feb7ca476d0960112846baf5a49c8028b2a /library/core/src | |
| parent | 7f75bfa1ad4e9a9d33a179a90603001515e91991 (diff) | |
| parent | 3c0c1386878812780349be38080470c0b4fcdda2 (diff) | |
| download | rust-4e5fec2f1ea4b1cfecaa14304c9f56de59b344cb.tar.gz rust-4e5fec2f1ea4b1cfecaa14304c9f56de59b344cb.zip | |
Auto merge of #134757 - RalfJung:const_swap, r=scottmcm
stabilize const_swap libs-api FCP passed in https://github.com/rust-lang/rust/issues/83163. However, I only just realized that this actually involves an intrinsic. The intrinsic could be implemented entirely with existing stable const functionality, but we choose to make it a primitive to be able to detect more UB. So nominating for `@rust-lang/lang` to make sure they are aware; I leave it up to them whether they want to FCP this. While at it I also renamed the intrinsic to make the "nonoverlapping" constraint more clear. Fixes #83163
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/intrinsics/mod.rs | 22 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/mem/mod.rs | 4 | ||||
| -rw-r--r-- | library/core/src/ptr/mod.rs | 3 | ||||
| -rw-r--r-- | library/core/src/ptr/mut_ptr.rs | 2 | ||||
| -rw-r--r-- | library/core/src/ptr/non_null.rs | 2 | ||||
| -rw-r--r-- | library/core/src/slice/mod.rs | 2 |
7 files changed, 25 insertions, 11 deletions
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 65e2dcbc7cc..b5c31d82467 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -3969,6 +3969,21 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool { false } +#[rustc_nounwind] +#[inline] +#[rustc_intrinsic] +#[rustc_intrinsic_const_stable_indirect] +#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic +#[cfg(bootstrap)] +pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) { + // SAFETY: The caller provided single non-overlapping items behind + // pointers, so swapping them with `count: 1` is fine. + unsafe { ptr::swap_nonoverlapping(x, y, 1) }; +} + +#[cfg(bootstrap)] +pub use typed_swap as typed_swap_nonoverlapping; + /// Non-overlapping *typed* swap of a single value. /// /// The codegen backends will replace this with a better implementation when @@ -3982,9 +3997,10 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool { #[rustc_nounwind] #[inline] #[rustc_intrinsic] -// Const-unstable because `swap_nonoverlapping` is const-unstable. -#[rustc_const_unstable(feature = "const_typed_swap", issue = "none")] -pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) { +#[rustc_intrinsic_const_stable_indirect] +#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic +#[cfg(not(bootstrap))] +pub const unsafe fn typed_swap_nonoverlapping<T>(x: *mut T, y: *mut T) { // SAFETY: The caller provided single non-overlapping items behind // pointers, so swapping them with `count: 1` is fine. unsafe { ptr::swap_nonoverlapping(x, y, 1) }; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 82d7d045bf5..0d8a3811ede 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -112,7 +112,6 @@ #![feature(asm_experimental_arch)] #![feature(const_carrying_mul_add)] #![feature(const_eval_select)] -#![feature(const_typed_swap)] #![feature(core_intrinsics)] #![feature(coverage_attribute)] #![feature(internal_impls_macro)] diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs index 57acc9dcd6e..2d66e5c2f2a 100644 --- a/library/core/src/mem/mod.rs +++ b/library/core/src/mem/mod.rs @@ -725,12 +725,12 @@ pub unsafe fn uninitialized<T>() -> T { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "mem_swap"] pub const fn swap<T>(x: &mut T, y: &mut T) { // SAFETY: `&mut` guarantees these are typed readable and writable // as well as non-overlapping. - unsafe { intrinsics::typed_swap(x, y) } + unsafe { intrinsics::typed_swap_nonoverlapping(x, y) } } /// Replaces `dest` with the default value of `T`, returning the previous `dest` value. diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index e6e13eaff7b..ac074c097d9 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1009,9 +1009,8 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_swap", issue = "83163")] +#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[rustc_diagnostic_item = "ptr_swap"] -#[rustc_const_stable_indirect] pub const unsafe fn swap<T>(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with. // We do not have to worry about drops: `MaybeUninit` does nothing when dropped. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 34567917b52..d75d570a969 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -1594,7 +1594,7 @@ impl<T: ?Sized> *mut T { /// /// [`ptr::swap`]: crate::ptr::swap() #[stable(feature = "pointer_methods", since = "1.26.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[inline(always)] pub const unsafe fn swap(self, with: *mut T) where diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index e0ba469272e..1058fa42cc1 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -1146,7 +1146,7 @@ impl<T: ?Sized> NonNull<T> { /// [`ptr::swap`]: crate::ptr::swap() #[inline(always)] #[stable(feature = "non_null_convenience", since = "1.80.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] pub const unsafe fn swap(self, with: NonNull<T>) where T: Sized, diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index ab65f9d6d2f..3e8c698a7ab 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -913,7 +913,7 @@ impl<T> [T] { /// assert!(v == ["a", "b", "e", "d", "c"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_swap", issue = "83163")] + #[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")] #[inline] #[track_caller] pub const fn swap(&mut self, a: usize, b: usize) { |
