|
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