114
114
//! [`impl Init<T, E>`]: Init
115
115
//! [`Opaque`]: kernel::types::Opaque
116
116
//! [`pin_data`]: ::macros::pin_data
117
- //! [`UniqueArc<T>`]: kernel::sync::UniqueArc
118
117
118
+ use crate :: {
119
+ error:: { self , Error } ,
120
+ sync:: UniqueArc ,
121
+ } ;
119
122
use alloc:: boxed:: Box ;
120
- use core:: { cell:: Cell , convert:: Infallible , marker:: PhantomData , mem:: MaybeUninit , ptr} ;
123
+ use core:: {
124
+ alloc:: AllocError , cell:: Cell , convert:: Infallible , marker:: PhantomData , mem:: MaybeUninit ,
125
+ pin:: Pin , ptr,
126
+ } ;
121
127
122
128
#[ doc( hidden) ]
123
129
pub mod __internal;
@@ -309,7 +315,6 @@ pub mod macros;
309
315
///
310
316
/// [`try_pin_init!`]: kernel::try_pin_init
311
317
/// [`NonNull<Self>`]: core::ptr::NonNull
312
- /// [`Error`]: kernel::error::Error
313
318
// For a detailed example of how this macro works, see the module documentation of the hidden
314
319
// module `__internal` inside of `init/__internal.rs`.
315
320
#[ macro_export]
@@ -363,8 +368,6 @@ macro_rules! pin_init {
363
368
/// }
364
369
/// }
365
370
/// ```
366
- ///
367
- /// [`Error`]: kernel::error::Error
368
371
// For a detailed example of how this macro works, see the module documentation of the hidden
369
372
// module `__internal` inside of `init/__internal.rs`.
370
373
#[ macro_export]
@@ -586,8 +589,6 @@ macro_rules! try_pin_init {
586
589
///
587
590
/// This initializer is for initializing data in-place that might later be moved. If you want to
588
591
/// pin-initialize, use [`pin_init!`].
589
- ///
590
- /// [`Error`]: kernel::error::Error
591
592
// For a detailed example of how this macro works, see the module documentation of the hidden
592
593
// module `__internal` inside of `init/__internal.rs`.
593
594
#[ macro_export]
@@ -635,8 +636,6 @@ macro_rules! init {
635
636
/// }
636
637
/// }
637
638
/// ```
638
- ///
639
- /// [`Error`]: kernel::error::Error
640
639
// For a detailed example of how this macro works, see the module documentation of the hidden
641
640
// module `__internal` inside of `init/__internal.rs`.
642
641
#[ macro_export]
@@ -842,7 +841,8 @@ macro_rules! try_init {
842
841
/// A pin-initializer for the type `T`.
843
842
///
844
843
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
845
- /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`].
844
+ /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`]. Use the [`InPlaceInit::pin_init`] function of a
845
+ /// smart pointer like [`Arc<T>`] on this.
846
846
///
847
847
/// Also see the [module description](self).
848
848
///
@@ -861,7 +861,6 @@ macro_rules! try_init {
861
861
///
862
862
/// [`Arc<T>`]: crate::sync::Arc
863
863
/// [`Arc::pin_init`]: crate::sync::Arc::pin_init
864
- /// [`UniqueArc<T>`]: kernel::sync::UniqueArc
865
864
#[ must_use = "An initializer must be used in order to create its value." ]
866
865
pub unsafe trait PinInit < T : ?Sized , E = Infallible > : Sized {
867
866
/// Initializes `slot`.
@@ -878,7 +877,8 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
878
877
/// An initializer for `T`.
879
878
///
880
879
/// To use this initializer, you will need a suitable memory location that can hold a `T`. This can
881
- /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`]. Because [`PinInit<T, E>`] is a super trait, you can
880
+ /// be [`Box<T>`], [`Arc<T>`], [`UniqueArc<T>`]. Use the [`InPlaceInit::init`] function of a smart
881
+ /// pointer like [`Arc<T>`] on this. Because [`PinInit<T, E>`] is a super trait, you can
882
882
/// use every function that takes it as well.
883
883
///
884
884
/// Also see the [module description](self).
@@ -903,7 +903,6 @@ pub unsafe trait PinInit<T: ?Sized, E = Infallible>: Sized {
903
903
/// move the pointee after initialization.
904
904
///
905
905
/// [`Arc<T>`]: crate::sync::Arc
906
- /// [`UniqueArc<T>`]: kernel::sync::UniqueArc
907
906
#[ must_use = "An initializer must be used in order to create its value." ]
908
907
pub unsafe trait Init < T : ?Sized , E = Infallible > : Sized {
909
908
/// Initializes `slot`.
@@ -982,3 +981,106 @@ unsafe impl<T> Init<T> for T {
982
981
Ok ( ( ) )
983
982
}
984
983
}
984
+
985
+ /// Smart pointer that can initialize memory in-place.
986
+ pub trait InPlaceInit < T > : Sized {
987
+ /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
988
+ /// type.
989
+ ///
990
+ /// If `T: !Unpin` it will not be able to move afterwards.
991
+ fn try_pin_init < E > ( init : impl PinInit < T , E > ) -> Result < Pin < Self > , E >
992
+ where
993
+ E : From < AllocError > ;
994
+
995
+ /// Use the given pin-initializer to pin-initialize a `T` inside of a new smart pointer of this
996
+ /// type.
997
+ ///
998
+ /// If `T: !Unpin` it will not be able to move afterwards.
999
+ fn pin_init < E > ( init : impl PinInit < T , E > ) -> error:: Result < Pin < Self > >
1000
+ where
1001
+ Error : From < E > ,
1002
+ {
1003
+ // SAFETY: We delegate to `init` and only change the error type.
1004
+ let init = unsafe {
1005
+ pin_init_from_closure ( |slot| init. __pinned_init ( slot) . map_err ( |e| Error :: from ( e) ) )
1006
+ } ;
1007
+ Self :: try_pin_init ( init)
1008
+ }
1009
+
1010
+ /// Use the given initializer to in-place initialize a `T`.
1011
+ fn try_init < E > ( init : impl Init < T , E > ) -> Result < Self , E >
1012
+ where
1013
+ E : From < AllocError > ;
1014
+
1015
+ /// Use the given initializer to in-place initialize a `T`.
1016
+ fn init < E > ( init : impl Init < T , E > ) -> error:: Result < Self >
1017
+ where
1018
+ Error : From < E > ,
1019
+ {
1020
+ // SAFETY: We delegate to `init` and only change the error type.
1021
+ let init = unsafe {
1022
+ init_from_closure ( |slot| init. __pinned_init ( slot) . map_err ( |e| Error :: from ( e) ) )
1023
+ } ;
1024
+ Self :: try_init ( init)
1025
+ }
1026
+ }
1027
+
1028
+ impl < T > InPlaceInit < T > for Box < T > {
1029
+ #[ inline]
1030
+ fn try_pin_init < E > ( init : impl PinInit < T , E > ) -> Result < Pin < Self > , E >
1031
+ where
1032
+ E : From < AllocError > ,
1033
+ {
1034
+ let mut this = Box :: try_new_uninit ( ) ?;
1035
+ let slot = this. as_mut_ptr ( ) ;
1036
+ // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1037
+ // slot is valid and will not be moved, because we pin it later.
1038
+ unsafe { init. __pinned_init ( slot) ? } ;
1039
+ // SAFETY: All fields have been initialized.
1040
+ Ok ( unsafe { this. assume_init ( ) } . into ( ) )
1041
+ }
1042
+
1043
+ #[ inline]
1044
+ fn try_init < E > ( init : impl Init < T , E > ) -> Result < Self , E >
1045
+ where
1046
+ E : From < AllocError > ,
1047
+ {
1048
+ let mut this = Box :: try_new_uninit ( ) ?;
1049
+ let slot = this. as_mut_ptr ( ) ;
1050
+ // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1051
+ // slot is valid.
1052
+ unsafe { init. __init ( slot) ? } ;
1053
+ // SAFETY: All fields have been initialized.
1054
+ Ok ( unsafe { this. assume_init ( ) } )
1055
+ }
1056
+ }
1057
+
1058
+ impl < T > InPlaceInit < T > for UniqueArc < T > {
1059
+ #[ inline]
1060
+ fn try_pin_init < E > ( init : impl PinInit < T , E > ) -> Result < Pin < Self > , E >
1061
+ where
1062
+ E : From < AllocError > ,
1063
+ {
1064
+ let mut this = UniqueArc :: try_new_uninit ( ) ?;
1065
+ let slot = this. as_mut_ptr ( ) ;
1066
+ // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1067
+ // slot is valid and will not be moved, because we pin it later.
1068
+ unsafe { init. __pinned_init ( slot) ? } ;
1069
+ // SAFETY: All fields have been initialized.
1070
+ Ok ( unsafe { this. assume_init ( ) } . into ( ) )
1071
+ }
1072
+
1073
+ #[ inline]
1074
+ fn try_init < E > ( init : impl Init < T , E > ) -> Result < Self , E >
1075
+ where
1076
+ E : From < AllocError > ,
1077
+ {
1078
+ let mut this = UniqueArc :: try_new_uninit ( ) ?;
1079
+ let slot = this. as_mut_ptr ( ) ;
1080
+ // SAFETY: When init errors/panics, slot will get deallocated but not dropped,
1081
+ // slot is valid.
1082
+ unsafe { init. __init ( slot) ? } ;
1083
+ // SAFETY: All fields have been initialized.
1084
+ Ok ( unsafe { this. assume_init ( ) } )
1085
+ }
1086
+ }
0 commit comments