|
212 | 212 | //! [`pin_data`]: ::macros::pin_data |
213 | 213 | //! [`pin_init!`]: crate::pin_init! |
214 | 214 |
|
215 | | -use crate::{alloc::KBox, types::ScopeGuard}; |
216 | 215 | use core::{ |
217 | 216 | cell::UnsafeCell, |
218 | 217 | convert::Infallible, |
@@ -944,7 +943,7 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized { |
944 | 943 | } |
945 | 944 |
|
946 | 945 | /// An initializer returned by [`PinInit::pin_chain`]. |
947 | | -pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, KBox<T>)>); |
| 946 | +pub struct ChainPinInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>); |
948 | 947 |
|
949 | 948 | // SAFETY: The `__pinned_init` function is implemented such that it |
950 | 949 | // - returns `Ok(())` on successful initialization, |
@@ -1043,7 +1042,7 @@ pub unsafe trait Init<T: ?Sized, E = Infallible>: PinInit<T, E> { |
1043 | 1042 | } |
1044 | 1043 |
|
1045 | 1044 | /// An initializer returned by [`Init::chain`]. |
1046 | | -pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, KBox<T>)>); |
| 1045 | +pub struct ChainInit<I, F, T: ?Sized, E>(I, F, __internal::Invariant<(E, T)>); |
1047 | 1046 |
|
1048 | 1047 | // SAFETY: The `__init` function is implemented such that it |
1049 | 1048 | // - returns `Ok(())` on successful initialization, |
@@ -1140,25 +1139,19 @@ where |
1140 | 1139 | { |
1141 | 1140 | let init = move |slot: *mut [T; N]| { |
1142 | 1141 | let slot = slot.cast::<T>(); |
1143 | | - // Counts the number of initialized elements and when dropped drops that many elements from |
1144 | | - // `slot`. |
1145 | | - let mut init_count = ScopeGuard::new_with_data(0, |i| { |
1146 | | - // We now free every element that has been initialized before. |
1147 | | - // SAFETY: The loop initialized exactly the values from 0..i and since we |
1148 | | - // return `Err` below, the caller will consider the memory at `slot` as |
1149 | | - // uninitialized. |
1150 | | - unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; |
1151 | | - }); |
1152 | 1142 | for i in 0..N { |
1153 | 1143 | let init = make_init(i); |
1154 | 1144 | // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`. |
1155 | 1145 | let ptr = unsafe { slot.add(i) }; |
1156 | 1146 | // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init` |
1157 | 1147 | // requirements. |
1158 | | - unsafe { init.__init(ptr) }?; |
1159 | | - *init_count += 1; |
| 1148 | + if let Err(e) = unsafe { init.__init(ptr) } { |
| 1149 | + // SAFETY: The loop has initialized the elements `slot[0..i]` and since we return |
| 1150 | + // `Err` below, `slot` will be considered uninitialized memory. |
| 1151 | + unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; |
| 1152 | + return Err(e); |
| 1153 | + } |
1160 | 1154 | } |
1161 | | - init_count.dismiss(); |
1162 | 1155 | Ok(()) |
1163 | 1156 | }; |
1164 | 1157 | // SAFETY: The initializer above initializes every element of the array. On failure it drops |
@@ -1189,25 +1182,19 @@ where |
1189 | 1182 | { |
1190 | 1183 | let init = move |slot: *mut [T; N]| { |
1191 | 1184 | let slot = slot.cast::<T>(); |
1192 | | - // Counts the number of initialized elements and when dropped drops that many elements from |
1193 | | - // `slot`. |
1194 | | - let mut init_count = ScopeGuard::new_with_data(0, |i| { |
1195 | | - // We now free every element that has been initialized before. |
1196 | | - // SAFETY: The loop initialized exactly the values from 0..i and since we |
1197 | | - // return `Err` below, the caller will consider the memory at `slot` as |
1198 | | - // uninitialized. |
1199 | | - unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; |
1200 | | - }); |
1201 | 1185 | for i in 0..N { |
1202 | 1186 | let init = make_init(i); |
1203 | 1187 | // SAFETY: Since 0 <= `i` < N, it is still in bounds of `[T; N]`. |
1204 | 1188 | let ptr = unsafe { slot.add(i) }; |
1205 | 1189 | // SAFETY: The pointer is derived from `slot` and thus satisfies the `__init` |
1206 | 1190 | // requirements. |
1207 | | - unsafe { init.__pinned_init(ptr) }?; |
1208 | | - *init_count += 1; |
| 1191 | + if let Err(e) = unsafe { init.__pinned_init(ptr) } { |
| 1192 | + // SAFETY: The loop has initialized the elements `slot[0..i]` and since we return |
| 1193 | + // `Err` below, `slot` will be considered uninitialized memory. |
| 1194 | + unsafe { ptr::drop_in_place(ptr::slice_from_raw_parts_mut(slot, i)) }; |
| 1195 | + return Err(e); |
| 1196 | + } |
1209 | 1197 | } |
1210 | | - init_count.dismiss(); |
1211 | 1198 | Ok(()) |
1212 | 1199 | }; |
1213 | 1200 | // SAFETY: The initializer above initializes every element of the array. On failure it drops |
|
0 commit comments