From 254c1ece7bfe79a49dbda4987972a7693127df39 Mon Sep 17 00:00:00 2001 From: matt rice Date: Sat, 9 Mar 2024 05:10:14 -0800 Subject: [PATCH] Fix Clone impl for miri stacked-borrows model This clone impl would sucessfully run under `MIRIFLAGS=-Zmiri-tree-borrows` but failed with stacked borrows. Instead of cloning the extra capacity into the new vec. Create a new vector with the correct capacity then extend it with the cloned contents of the other vector. This can be done safely. --- src/core/option.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/core/option.rs b/src/core/option.rs index 80f50f4..a8f7a42 100644 --- a/src/core/option.rs +++ b/src/core/option.rs @@ -242,15 +242,10 @@ impl Clone for OptionCore { // is important for us. // - The memory after its length is probably uninitialized. // - // To fix both issues, we get a slice to the complete memory of the - // original `Vec` and create a `Vec` from it. Then we reset the length - // to the old value. Both is safe as all the elements that are included - // and excluded by the "fake length" are `None`. - let data = unsafe { - let mut data_clone = self.data.get_unchecked(0..self.data.capacity()).to_vec(); - data_clone.set_len(self.data.len()); - data_clone - }; + // To fix both issues, we create a new vec with the appopriate capacity + // and extend it with the values of the other. + let mut data = Vec::with_capacity(self.data.capacity()); + data.extend(self.data.iter().cloned()); Self { data } }