diff options
| author | Yuki Okushi <jtitor@2k36.org> | 2021-10-21 14:11:13 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-21 14:11:13 +0900 |
| commit | 3680ecd8a6e8dcac98833bc8bbc349277f780419 (patch) | |
| tree | c96cd17109ce7c0f9bd8ea0e2d5ab1e4f6cf56ef | |
| parent | 68a5680fc5961f1c91e79debae2f0994c1136a69 (diff) | |
| parent | 0aa68a8db9dfffb2756279cc621b1b15a896423d (diff) | |
| download | rust-3680ecd8a6e8dcac98833bc8bbc349277f780419.tar.gz rust-3680ecd8a6e8dcac98833bc8bbc349277f780419.zip | |
Rollup merge of #90099 - SkiFire13:fix-vec-swap-remove, r=dtolnay
Fix MIRI UB in `Vec::swap_remove` Fixes #90055 I find it weird that `Vec::swap_remove` read the last element to the stack just to immediately put it back in the `Vec` in place of the one at index `index`. It seems much more natural to me to just read the element at position `index` and then move the last element in its place. I guess this might also slightly improve codegen.
| -rw-r--r-- | library/alloc/src/vec/mod.rs | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 20a16869cb3..d52c78eedf3 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -1305,10 +1305,11 @@ impl<T, A: Allocator> Vec<T, A> { // We replace self[index] with the last element. Note that if the // bounds check above succeeds there must be a last element (which // can be self[index] itself). - let last = ptr::read(self.as_ptr().add(len - 1)); - let hole = self.as_mut_ptr().add(index); + let value = ptr::read(self.as_ptr().add(index)); + let base_ptr = self.as_mut_ptr(); + ptr::copy(base_ptr.add(len - 1), base_ptr.add(index), 1); self.set_len(len - 1); - ptr::replace(hole, last) + value } } |
