about summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-12-30 23:46:42 +0000
committerbors <bors@rust-lang.org>2024-12-30 23:46:42 +0000
commit4e5fec2f1ea4b1cfecaa14304c9f56de59b344cb (patch)
tree1e4e8feb7ca476d0960112846baf5a49c8028b2a /library/core/src
parent7f75bfa1ad4e9a9d33a179a90603001515e91991 (diff)
parent3c0c1386878812780349be38080470c0b4fcdda2 (diff)
downloadrust-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.rs22
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/mem/mod.rs4
-rw-r--r--library/core/src/ptr/mod.rs3
-rw-r--r--library/core/src/ptr/mut_ptr.rs2
-rw-r--r--library/core/src/ptr/non_null.rs2
-rw-r--r--library/core/src/slice/mod.rs2
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) {