@@ -1137,27 +1137,15 @@ impl<T> InPlaceInit<T> for Box<T> {
1137
1137
where
1138
1138
E : From < AllocError > ,
1139
1139
{
1140
- let mut this = Box :: try_new_uninit ( ) ?;
1141
- let slot = this. as_mut_ptr ( ) ;
1142
- // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1143
- // slot is valid and will not be moved, because we pin it later.
1144
- unsafe { init. __pinned_init ( slot) ? } ;
1145
- // SAFETY: All fields have been initialized.
1146
- Ok ( unsafe { this. assume_init ( ) } . into ( ) )
1140
+ Box :: try_new_uninit ( ) ?. write_pin_init ( init)
1147
1141
}
1148
1142
1149
1143
#[ inline]
1150
1144
fn try_init < E > ( init : impl Init < T , E > ) -> Result < Self , E >
1151
1145
where
1152
1146
E : From < AllocError > ,
1153
1147
{
1154
- let mut this = Box :: try_new_uninit ( ) ?;
1155
- let slot = this. as_mut_ptr ( ) ;
1156
- // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1157
- // slot is valid.
1158
- unsafe { init. __init ( slot) ? } ;
1159
- // SAFETY: All fields have been initialized.
1160
- Ok ( unsafe { this. assume_init ( ) } )
1148
+ Box :: try_new_uninit ( ) ?. write_init ( init)
1161
1149
}
1162
1150
}
1163
1151
@@ -1168,29 +1156,79 @@ impl<T> InPlaceInit<T> for Arc<T> {
1168
1156
where
1169
1157
E : From < AllocError > ,
1170
1158
{
1171
- let mut this = Arc :: try_new_uninit ( ) ?;
1172
- let slot = unsafe { Arc :: get_mut_unchecked ( & mut this) } ;
1173
- let slot = slot. as_mut_ptr ( ) ;
1174
- // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1175
- // slot is valid and will not be moved, because we pin it later.
1176
- unsafe { init. __pinned_init ( slot) ? } ;
1177
- // SAFETY: All fields have been initialized and this is the only `Arc` to that data.
1178
- Ok ( unsafe { Pin :: new_unchecked ( this. assume_init ( ) ) } )
1159
+ Arc :: try_new_uninit ( ) ?. write_pin_init ( init)
1179
1160
}
1180
1161
1181
1162
#[ inline]
1182
1163
fn try_init < E > ( init : impl Init < T , E > ) -> Result < Self , E >
1183
1164
where
1184
1165
E : From < AllocError > ,
1185
1166
{
1186
- let mut this = Arc :: try_new_uninit ( ) ?;
1187
- let slot = unsafe { Arc :: get_mut_unchecked ( & mut this) } ;
1167
+ Arc :: try_new_uninit ( ) ?. write_init ( init)
1168
+ }
1169
+ }
1170
+
1171
+ /// Smart pointer containing uninitialized memory and that can write a value.
1172
+ pub trait InPlaceWrite < T > {
1173
+ /// The type `Self` turns into when the contents are initialized.
1174
+ type Initialized ;
1175
+
1176
+ /// Use the given initializer to write a value into `self`.
1177
+ ///
1178
+ /// Does not drop the current value and considers it as uninitialized memory.
1179
+ fn write_init < E > ( self , init : impl Init < T , E > ) -> Result < Self :: Initialized , E > ;
1180
+
1181
+ /// Use the given pin-initializer to write a value into `self`.
1182
+ ///
1183
+ /// Does not drop the current value and considers it as uninitialized memory.
1184
+ fn write_pin_init < E > ( self , init : impl PinInit < T , E > ) -> Result < Pin < Self :: Initialized > , E > ;
1185
+ }
1186
+
1187
+ #[ cfg( feature = "alloc" ) ]
1188
+ impl < T > InPlaceWrite < T > for Box < MaybeUninit < T > > {
1189
+ type Initialized = Box < T > ;
1190
+
1191
+ fn write_init < E > ( mut self , init : impl Init < T , E > ) -> Result < Self :: Initialized , E > {
1192
+ let slot = self . as_mut_ptr ( ) ;
1193
+ // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1194
+ // slot is valid.
1195
+ unsafe { init. __init ( slot) ? } ;
1196
+ // SAFETY: All fields have been initialized.
1197
+ Ok ( unsafe { self . assume_init ( ) } )
1198
+ }
1199
+
1200
+ fn write_pin_init < E > ( mut self , init : impl PinInit < T , E > ) -> Result < Pin < Self :: Initialized > , E > {
1201
+ let slot = self . as_mut_ptr ( ) ;
1202
+ // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1203
+ // slot is valid and will not be moved, because we pin it later.
1204
+ unsafe { init. __pinned_init ( slot) ? } ;
1205
+ // SAFETY: All fields have been initialized.
1206
+ Ok ( unsafe { self . assume_init ( ) } . into ( ) )
1207
+ }
1208
+ }
1209
+
1210
+ #[ cfg( feature = "alloc" ) ]
1211
+ impl < T > InPlaceWrite < T > for Arc < MaybeUninit < T > > {
1212
+ type Initialized = Arc < T > ;
1213
+
1214
+ fn write_init < E > ( mut self , init : impl Init < T , E > ) -> Result < Self :: Initialized , E > {
1215
+ let slot = unsafe { Arc :: get_mut_unchecked ( & mut self ) } ;
1188
1216
let slot = slot. as_mut_ptr ( ) ;
1189
1217
// SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1190
1218
// slot is valid.
1191
1219
unsafe { init. __init ( slot) ? } ;
1192
1220
// SAFETY: All fields have been initialized.
1193
- Ok ( unsafe { this. assume_init ( ) } )
1221
+ Ok ( unsafe { self . assume_init ( ) } )
1222
+ }
1223
+
1224
+ fn write_pin_init < E > ( mut self , init : impl PinInit < T , E > ) -> Result < Pin < Self :: Initialized > , E > {
1225
+ let slot = unsafe { Arc :: get_mut_unchecked ( & mut self ) } ;
1226
+ let slot = slot. as_mut_ptr ( ) ;
1227
+ // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1228
+ // slot is valid and will not be moved, because we pin it later.
1229
+ unsafe { init. __pinned_init ( slot) ? } ;
1230
+ // SAFETY: All fields have been initialized and this is the only `Arc` to that data.
1231
+ Ok ( unsafe { Pin :: new_unchecked ( self . assume_init ( ) ) } )
1194
1232
}
1195
1233
}
1196
1234
0 commit comments