about summary refs log tree commit diff
path: root/library/alloc/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-12-14 04:29:54 +0000
committerbors <bors@rust-lang.org>2021-12-14 04:29:54 +0000
commit7ca74ea0afe87b2cb173ea1fea190853c3c3d860 (patch)
tree0d6701ed0d157a9b1d717d47cbcca2e7e0779ed8 /library/alloc/src
parenta2d25b4ff71b3d8ec49dc6a384e65e6a3ea33116 (diff)
parent14f4ffae3224a7846c6bab33f9ca8593ec7416cf (diff)
downloadrust-7ca74ea0afe87b2cb173ea1fea190853c3c3d860.tar.gz
rust-7ca74ea0afe87b2cb173ea1fea190853c3c3d860.zip
Auto merge of #91680 - saethlin:spare_capacity_mut-in-join, r=dtolnay
Use spare_capacity_mut instead of invalid unchecked indexing when joining str

This is a fix for https://github.com/rust-lang/rust/issues/91574

I think in general I'd prefer to see this code implemented with raw pointers or `MaybeUninit::write_slice`, but there's existing code in here based on copying from slice to slice, so converting everything from `&[T]` to `&[MaybeUninit<T>]` is less disruptive.
Diffstat (limited to 'library/alloc/src')
-rw-r--r--library/alloc/src/str.rs12
1 files changed, 10 insertions, 2 deletions
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index 104f5556566..69495f31c32 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -178,12 +178,20 @@ where
 
     unsafe {
         let pos = result.len();
-        let target = result.get_unchecked_mut(pos..reserved_len);
+        let target = result.spare_capacity_mut().get_unchecked_mut(..reserved_len - pos);
+
+        // Convert the separator and slices to slices of MaybeUninit
+        // to simplify implementation in specialize_for_lengths
+        let sep_uninit = core::slice::from_raw_parts(sep.as_ptr().cast(), sep.len());
+        let iter_uninit = iter.map(|it| {
+            let it = it.borrow().as_ref();
+            core::slice::from_raw_parts(it.as_ptr().cast(), it.len())
+        });
 
         // copy separator and slices over without bounds checks
         // generate loops with hardcoded offsets for small separators
         // massive improvements possible (~ x2)
-        let remain = specialize_for_lengths!(sep, target, iter; 0, 1, 2, 3, 4);
+        let remain = specialize_for_lengths!(sep_uninit, target, iter_uninit; 0, 1, 2, 3, 4);
 
         // A weird borrow implementation may return different
         // slices for the length calculation and the actual copy.