diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index baa6c0919defe..cb4c1c20abcf6 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -1410,6 +1410,11 @@ impl Vec { assert_failed(at, self.len()); } + if at == 0 { + // the new vector can take over the original buffer and avoid the copy + return mem::replace(self, Vec::with_capacity(self.capacity())); + } + let other_len = self.len - at; let mut other = Vec::with_capacity(other_len); diff --git a/library/alloc/tests/string.rs b/library/alloc/tests/string.rs index 6059bec8c5a3d..f7f78046d089b 100644 --- a/library/alloc/tests/string.rs +++ b/library/alloc/tests/string.rs @@ -278,17 +278,21 @@ fn test_split_off_mid_char() { #[test] fn test_split_off_ascii() { let mut ab = String::from("ABCD"); + let orig_capacity = ab.capacity(); let cd = ab.split_off(2); assert_eq!(ab, "AB"); assert_eq!(cd, "CD"); + assert_eq!(ab.capacity(), orig_capacity); } #[test] fn test_split_off_unicode() { let mut nihon = String::from("日本語"); + let orig_capacity = nihon.capacity(); let go = nihon.split_off("日本".len()); assert_eq!(nihon, "日本"); assert_eq!(go, "語"); + assert_eq!(nihon.capacity(), orig_capacity); } #[test] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 5f7a9399453ea..608a3c9bdf762 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -772,9 +772,23 @@ fn test_append() { #[test] fn test_split_off() { let mut vec = vec![1, 2, 3, 4, 5, 6]; + let orig_capacity = vec.capacity(); let vec2 = vec.split_off(4); assert_eq!(vec, [1, 2, 3, 4]); assert_eq!(vec2, [5, 6]); + assert_eq!(vec.capacity(), orig_capacity); +} + +#[test] +fn test_split_off_take_all() { + let mut vec = vec![1, 2, 3, 4, 5, 6]; + let orig_ptr = vec.as_ptr(); + let orig_capacity = vec.capacity(); + let vec2 = vec.split_off(0); + assert_eq!(vec, []); + assert_eq!(vec2, [1, 2, 3, 4, 5, 6]); + assert_eq!(vec.capacity(), orig_capacity); + assert_eq!(vec2.as_ptr(), orig_ptr); } #[test]