@@ -1137,27 +1137,15 @@ impl<T> InPlaceInit<T> for Box<T> {
11371137 where
11381138 E : From < AllocError > ,
11391139 {
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)
11471141 }
11481142
11491143 #[ inline]
11501144 fn try_init < E > ( init : impl Init < T , E > ) -> Result < Self , E >
11511145 where
11521146 E : From < AllocError > ,
11531147 {
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)
11611149 }
11621150}
11631151
@@ -1168,29 +1156,79 @@ impl<T> InPlaceInit<T> for Arc<T> {
11681156 where
11691157 E : From < AllocError > ,
11701158 {
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)
11791160 }
11801161
11811162 #[ inline]
11821163 fn try_init < E > ( init : impl Init < T , E > ) -> Result < Self , E >
11831164 where
11841165 E : From < AllocError > ,
11851166 {
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 ) } ;
11881216 let slot = slot. as_mut_ptr ( ) ;
11891217 // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
11901218 // slot is valid.
11911219 unsafe { init. __init ( slot) ? } ;
11921220 // 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 ( ) ) } )
11941232 }
11951233}
11961234
0 commit comments