2121//! implementation changes (using a special thread-local heap, for example).
2222//! Moreover, a switch to, e.g., `P<'a, T>` would be easy and mostly automated.
2323
24+ use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
25+ use rustc_data_structures:: stack:: ensure_sufficient_stack;
26+ use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
27+
2428use std:: fmt:: { self , Debug , Display } ;
2529use std:: iter:: FromIterator ;
30+ use std:: mem:: ManuallyDrop ;
2631use std:: ops:: { Deref , DerefMut } ;
2732use std:: { slice, vec} ;
2833
29- use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
30-
31- use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
3234/// An owned smart pointer.
3335pub struct P < T : ?Sized > {
34- ptr : Box < T > ,
36+ ptr : ManuallyDrop < Box < T > > ,
3537}
3638
3739/// Construct a `P<T>` from a `T` value.
3840#[ allow( non_snake_case) ]
3941pub fn P < T : ' static > ( value : T ) -> P < T > {
40- P { ptr : Box :: new ( value) }
42+ P :: from_box ( Box :: new ( value) )
43+ }
44+
45+ impl < T : ?Sized > P < T > {
46+ const fn from_box ( ptr : Box < T > ) -> P < T > {
47+ P { ptr : ManuallyDrop :: new ( ptr) }
48+ }
49+
50+ fn into_box ( self ) -> Box < T > {
51+ let mut this = ManuallyDrop :: new ( self ) ;
52+ unsafe { ManuallyDrop :: take ( & mut this. ptr ) }
53+ }
4154}
4255
4356impl < T : ' static > P < T > {
@@ -47,32 +60,38 @@ impl<T: 'static> P<T> {
4760 where
4861 F : FnOnce ( T ) -> U ,
4962 {
50- f ( * self . ptr )
63+ f ( * self . into_box ( ) )
5164 }
5265
5366 /// Equivalent to `and_then(|x| x)`.
5467 pub fn into_inner ( self ) -> T {
55- * self . ptr
68+ * self . into_box ( )
5669 }
5770
5871 /// Produce a new `P<T>` from `self` without reallocating.
59- pub fn map < F > ( mut self , f : F ) -> P < T >
72+ pub fn map < F > ( self , f : F ) -> P < T >
6073 where
6174 F : FnOnce ( T ) -> T ,
6275 {
63- let x = f ( * self . ptr ) ;
64- * self . ptr = x;
65-
66- self
76+ let mut ptr = self . into_box ( ) ;
77+ * ptr = f ( * ptr) ;
78+ P :: from_box ( ptr)
6779 }
6880
6981 /// Optionally produce a new `P<T>` from `self` without reallocating.
70- pub fn filter_map < F > ( mut self , f : F ) -> Option < P < T > >
82+ pub fn filter_map < F > ( self , f : F ) -> Option < P < T > >
7183 where
7284 F : FnOnce ( T ) -> Option < T > ,
7385 {
74- * self . ptr = f ( * self . ptr ) ?;
75- Some ( self )
86+ let mut ptr = self . into_box ( ) ;
87+ * ptr = f ( * ptr) ?;
88+ Some ( P :: from_box ( ptr) )
89+ }
90+ }
91+
92+ impl < T : ?Sized > Drop for P < T > {
93+ fn drop ( & mut self ) {
94+ ensure_sufficient_stack ( || unsafe { ManuallyDrop :: drop ( & mut self . ptr ) } ) ;
7695 }
7796}
7897
@@ -98,7 +117,7 @@ impl<T: 'static + Clone> Clone for P<T> {
98117
99118impl < T : ?Sized + Debug > Debug for P < T > {
100119 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
101- Debug :: fmt ( & self . ptr , f)
120+ Debug :: fmt ( & * self . ptr , f)
102121 }
103122}
104123
@@ -110,7 +129,7 @@ impl<T: Display> Display for P<T> {
110129
111130impl < T > fmt:: Pointer for P < T > {
112131 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
113- fmt:: Pointer :: fmt ( & self . ptr , f)
132+ fmt:: Pointer :: fmt ( & * self . ptr , f)
114133 }
115134}
116135
@@ -128,17 +147,17 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> {
128147
129148impl < T > P < [ T ] > {
130149 pub const fn new ( ) -> P < [ T ] > {
131- P { ptr : Box :: default ( ) }
150+ P :: from_box ( Box :: default ( ) )
132151 }
133152
134153 #[ inline( never) ]
135154 pub fn from_vec ( v : Vec < T > ) -> P < [ T ] > {
136- P { ptr : v. into_boxed_slice ( ) }
155+ P :: from_box ( v. into_boxed_slice ( ) )
137156 }
138157
139158 #[ inline( never) ]
140159 pub fn into_vec ( self ) -> Vec < T > {
141- self . ptr . into_vec ( )
160+ self . into_box ( ) . into_vec ( )
142161 }
143162}
144163
0 commit comments