diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index c9c73f4d66ee9..d93e5a9ca2b63 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2146,14 +2146,13 @@ impl [T] { /// Copying four bytes within a slice: /// /// ``` - /// # #![feature(copy_within)] /// let mut bytes = *b"Hello, World!"; /// /// bytes.copy_within(1..5, 8); /// /// assert_eq!(&bytes, b"Hello, Wello!"); /// ``` - #[unstable(feature = "copy_within", issue = "54236")] + #[stable(feature = "copy_within", since = "1.37.0")] pub fn copy_within>(&mut self, src: R, dest: usize) where T: Copy, @@ -2178,8 +2177,8 @@ impl [T] { assert!(dest <= self.len() - count, "dest is out of bounds"); unsafe { ptr::copy( - self.get_unchecked(src_start), - self.get_unchecked_mut(dest), + self.as_ptr().add(src_start), + self.as_mut_ptr().add(dest), count, ); } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 928bdd7a76002..bf072a9243b51 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -28,7 +28,6 @@ #![feature(inner_deref)] #![feature(slice_internals)] #![feature(slice_partition_dedup)] -#![feature(copy_within)] #![feature(int_error_matching)] #![feature(const_fn)] #![warn(rust_2018_idioms)] diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 9710f019f4e4d..eaa799fa96ee2 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1512,6 +1512,13 @@ fn test_copy_within() { let mut bytes = *b"Hello, World!"; bytes.copy_within(.., 0); assert_eq!(&bytes, b"Hello, World!"); + + // Ensure that copying at the end of slice won't cause UB. + let mut bytes = *b"Hello, World!"; + bytes.copy_within(13..13, 5); + assert_eq!(&bytes, b"Hello, World!"); + bytes.copy_within(5..5, 13); + assert_eq!(&bytes, b"Hello, World!"); } #[test] @@ -1536,6 +1543,13 @@ fn test_copy_within_panics_src_inverted() { // 2 is greater than 1, so this range is invalid. bytes.copy_within(2..1, 0); } +#[test] +#[should_panic(expected = "attempted to index slice up to maximum usize")] +fn test_copy_within_panics_src_out_of_bounds() { + let mut bytes = *b"Hello, World!"; + // an inclusive range ending at usize::max_value() would make src_end overflow + bytes.copy_within(usize::max_value()..=usize::max_value(), 0); +} #[test] fn test_is_sorted() {