@@ -87,7 +87,12 @@ impl BlobVec {
87
87
88
88
/// # Safety
89
89
/// - index must be in bounds
90
- /// - memory must be reserved and uninitialized
90
+ /// - the memory in the `BlobVec` starting at index `index`, of a size matching this `BlobVec`'s
91
+ /// `item_layout`, must have been previously allocated, but not initialized yet
92
+ /// - the memory at `*value` must be previously initialized with an item matching this
93
+ /// `BlobVec`'s `item_layout`
94
+ /// - the item that was stored in `*value` is left logically uninitialised/moved out of after
95
+ /// calling this function, and as such should not be used or dropped by the caller.
91
96
#[ inline]
92
97
pub unsafe fn initialize_unchecked ( & mut self , index : usize , value : * mut u8 ) {
93
98
debug_assert ! ( index < self . len( ) ) ;
@@ -97,12 +102,24 @@ impl BlobVec {
97
102
98
103
/// # Safety
99
104
/// - index must be in-bounds
100
- // - memory must be previously initialized
105
+ /// - the memory in the `BlobVec` starting at index `index`, of a size matching this `BlobVec`'s
106
+ /// `item_layout`, must have been previously initialized with an item matching this `BlobVec`'s
107
+ /// item_layout
108
+ /// - the memory at `*value` must also be previously initialized with an item matching this
109
+ /// `BlobVec`'s `item_layout`
110
+ /// - the item that was stored in `*value` is left logically uninitialised/moved out of after
111
+ /// calling this function, and as such should not be used or dropped by the caller.
101
112
pub unsafe fn replace_unchecked ( & mut self , index : usize , value : * mut u8 ) {
102
113
debug_assert ! ( index < self . len( ) ) ;
103
114
let ptr = self . get_unchecked ( index) ;
115
+ // If `drop` panics, then when the collection is dropped during stack unwinding, the
116
+ // collection's `Drop` impl will call `drop` again for the old value (which is still stored
117
+ // in the collection), so we get a double drop. To prevent that, we set len to 0 until we're
118
+ // done.
119
+ let old_len = std:: mem:: replace ( & mut self . len , 0 ) ;
104
120
( self . drop ) ( ptr) ;
105
121
std:: ptr:: copy_nonoverlapping ( value, ptr, self . item_layout . size ( ) ) ;
122
+ self . len = old_len;
106
123
}
107
124
108
125
/// increases the length by one (and grows the vec if needed) with uninitialized memory and
0 commit comments