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