@@ -1064,10 +1064,43 @@ pub const unsafe fn swap<T>(x: *mut T, y: *mut T) {
10641064/// assert_eq!(x, [7, 8, 3, 4]);
10651065/// assert_eq!(y, [1, 2, 9]);
10661066/// ```
1067+ ///
1068+ /// # Const evaluation limitations
1069+ ///
1070+ /// If this function is invoked during const-evaluation, the current implementation has a small (and
1071+ /// rarely relevant) limitation: if `count` is at least 2 and the data pointed to by `x` or `y`
1072+ /// contains a pointer that crosses the boundary of two `T`-sized chunks of memory, the function
1073+ /// may fail.
1074+ /// This is illustrated by the following example:
1075+ ///
1076+ /// ```
1077+ /// use std::mem::size_of;
1078+ /// use std::ptr;
1079+ ///
1080+ /// const { unsafe {
1081+ /// const PTR_SIZE: usize = size_of::<*const i32>();
1082+ /// let mut data1 = [0u8; PTR_SIZE];
1083+ /// let mut data2 = [0u8; PTR_SIZE];
1084+ /// // Store a pointer in `data1`.
1085+ /// data1.as_mut_ptr().cast::<*const i32>().write_unaligned(&42);
1086+ /// // Swap the contents of `data1` and `data2` by swapping `PTR_SIZE` many `u8`-sized chunks.
1087+ /// // This call will fail, because the pointer in `data1` crosses the boundary
1088+ /// // between several of the 1-byte chunks that are being swapped here.
1089+ /// //ptr::swap_nonoverlapping(data1.as_mut_ptr(), data2.as_mut_ptr(), PTR_SIZE);
1090+ /// // Swap the contents of `data1` and `data2` by swapping a single chunk of size
1091+ /// // `[u8; PTR_SIZE]`. That works, as there is no pointer crossing the boundary between
1092+ /// // two chunks.
1093+ /// ptr::swap_nonoverlapping(&mut data1, &mut data2, 1);
1094+ /// // Read the pointer from `data2` and dereference it.
1095+ /// let ptr = data2.as_ptr().cast::<*const i32>().read_unaligned();
1096+ /// assert!(*ptr == 42);
1097+ /// } }
1098+ /// ```
10671099#[ inline]
10681100#[ stable( feature = "swap_nonoverlapping" , since = "1.27.0" ) ]
1069- #[ rustc_const_unstable ( feature = "const_swap_nonoverlapping" , issue = "133668 " ) ]
1101+ #[ rustc_const_stable ( feature = "const_swap_nonoverlapping" , since = "CURRENT_RUSTC_VERSION " ) ]
10701102#[ rustc_diagnostic_item = "ptr_swap_nonoverlapping" ]
1103+ #[ rustc_allow_const_fn_unstable( const_eval_select) ] // both implementations behave the same
10711104pub const unsafe fn swap_nonoverlapping < T > ( x : * mut T , y : * mut T , count : usize ) {
10721105 ub_checks:: assert_unsafe_precondition!(
10731106 check_library_ub,
0 commit comments