Skip to content

Commit 27790d8

Browse files
borsgitbot
authored and
gitbot
committed
Auto merge of rust-lang#134757 - RalfJung:const_swap, r=scottmcm
stabilize const_swap libs-api FCP passed in rust-lang#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 rust-lang#83163
2 parents 6c8fda2 + 18e2c0d commit 27790d8

File tree

8 files changed

+25
-12
lines changed

8 files changed

+25
-12
lines changed

core/src/intrinsics/mod.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -3969,6 +3969,21 @@ pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
39693969
false
39703970
}
39713971

3972+
#[rustc_nounwind]
3973+
#[inline]
3974+
#[rustc_intrinsic]
3975+
#[rustc_intrinsic_const_stable_indirect]
3976+
#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic
3977+
#[cfg(bootstrap)]
3978+
pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
3979+
// SAFETY: The caller provided single non-overlapping items behind
3980+
// pointers, so swapping them with `count: 1` is fine.
3981+
unsafe { ptr::swap_nonoverlapping(x, y, 1) };
3982+
}
3983+
3984+
#[cfg(bootstrap)]
3985+
pub use typed_swap as typed_swap_nonoverlapping;
3986+
39723987
/// Non-overlapping *typed* swap of a single value.
39733988
///
39743989
/// 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 {
39823997
#[rustc_nounwind]
39833998
#[inline]
39843999
#[rustc_intrinsic]
3985-
// Const-unstable because `swap_nonoverlapping` is const-unstable.
3986-
#[rustc_const_unstable(feature = "const_typed_swap", issue = "none")]
3987-
pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
4000+
#[rustc_intrinsic_const_stable_indirect]
4001+
#[rustc_allow_const_fn_unstable(const_swap_nonoverlapping)] // this is anyway not called since CTFE implements the intrinsic
4002+
#[cfg(not(bootstrap))]
4003+
pub const unsafe fn typed_swap_nonoverlapping<T>(x: *mut T, y: *mut T) {
39884004
// SAFETY: The caller provided single non-overlapping items behind
39894005
// pointers, so swapping them with `count: 1` is fine.
39904006
unsafe { ptr::swap_nonoverlapping(x, y, 1) };

core/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@
112112
#![feature(asm_experimental_arch)]
113113
#![feature(const_carrying_mul_add)]
114114
#![feature(const_eval_select)]
115-
#![feature(const_typed_swap)]
116115
#![feature(core_intrinsics)]
117116
#![feature(coverage_attribute)]
118117
#![feature(internal_impls_macro)]

core/src/mem/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -725,12 +725,12 @@ pub unsafe fn uninitialized<T>() -> T {
725725
/// ```
726726
#[inline]
727727
#[stable(feature = "rust1", since = "1.0.0")]
728-
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
728+
#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
729729
#[rustc_diagnostic_item = "mem_swap"]
730730
pub const fn swap<T>(x: &mut T, y: &mut T) {
731731
// SAFETY: `&mut` guarantees these are typed readable and writable
732732
// as well as non-overlapping.
733-
unsafe { intrinsics::typed_swap(x, y) }
733+
unsafe { intrinsics::typed_swap_nonoverlapping(x, y) }
734734
}
735735

736736
/// Replaces `dest` with the default value of `T`, returning the previous `dest` value.

core/src/ptr/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1009,9 +1009,8 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
10091009
/// ```
10101010
#[inline]
10111011
#[stable(feature = "rust1", since = "1.0.0")]
1012-
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
1012+
#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
10131013
#[rustc_diagnostic_item = "ptr_swap"]
1014-
#[rustc_const_stable_indirect]
10151014
pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
10161015
// Give ourselves some scratch space to work with.
10171016
// We do not have to worry about drops: `MaybeUninit` does nothing when dropped.

core/src/ptr/mut_ptr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1594,7 +1594,7 @@ impl<T: ?Sized> *mut T {
15941594
///
15951595
/// [`ptr::swap`]: crate::ptr::swap()
15961596
#[stable(feature = "pointer_methods", since = "1.26.0")]
1597-
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
1597+
#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
15981598
#[inline(always)]
15991599
pub const unsafe fn swap(self, with: *mut T)
16001600
where

core/src/ptr/non_null.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1146,7 +1146,7 @@ impl<T: ?Sized> NonNull<T> {
11461146
/// [`ptr::swap`]: crate::ptr::swap()
11471147
#[inline(always)]
11481148
#[stable(feature = "non_null_convenience", since = "1.80.0")]
1149-
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
1149+
#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
11501150
pub const unsafe fn swap(self, with: NonNull<T>)
11511151
where
11521152
T: Sized,

core/src/slice/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ impl<T> [T] {
913913
/// assert!(v == ["a", "b", "e", "d", "c"]);
914914
/// ```
915915
#[stable(feature = "rust1", since = "1.0.0")]
916-
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
916+
#[rustc_const_stable(feature = "const_swap", since = "CURRENT_RUSTC_VERSION")]
917917
#[inline]
918918
#[track_caller]
919919
pub const fn swap(&mut self, a: usize, b: usize) {

core/tests/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#![feature(clone_to_uninit)]
1616
#![feature(const_black_box)]
1717
#![feature(const_eval_select)]
18-
#![feature(const_swap)]
1918
#![feature(const_swap_nonoverlapping)]
2019
#![feature(const_trait_impl)]
2120
#![feature(core_intrinsics)]

0 commit comments

Comments
 (0)