21
21
//! implementation changes (using a special thread-local heap, for example).
22
22
//! Moreover, a switch to, e.g., `P<'a, T>` would be easy and mostly automated.
23
23
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
+
24
28
use std:: fmt:: { self , Debug , Display } ;
25
29
use std:: iter:: FromIterator ;
30
+ use std:: mem:: ManuallyDrop ;
26
31
use std:: ops:: { Deref , DerefMut } ;
27
32
use std:: { slice, vec} ;
28
33
29
- use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
30
-
31
- use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
32
34
/// An owned smart pointer.
33
35
pub struct P < T : ?Sized > {
34
- ptr : Box < T > ,
36
+ ptr : ManuallyDrop < Box < T > > ,
35
37
}
36
38
37
39
/// Construct a `P<T>` from a `T` value.
38
40
#[ allow( non_snake_case) ]
39
41
pub 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
+ }
41
54
}
42
55
43
56
impl < T : ' static > P < T > {
@@ -47,32 +60,38 @@ impl<T: 'static> P<T> {
47
60
where
48
61
F : FnOnce ( T ) -> U ,
49
62
{
50
- f ( * self . ptr )
63
+ f ( * self . into_box ( ) )
51
64
}
52
65
53
66
/// Equivalent to `and_then(|x| x)`.
54
67
pub fn into_inner ( self ) -> T {
55
- * self . ptr
68
+ * self . into_box ( )
56
69
}
57
70
58
71
/// 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 >
60
73
where
61
74
F : FnOnce ( T ) -> T ,
62
75
{
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)
67
79
}
68
80
69
81
/// 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 > >
71
83
where
72
84
F : FnOnce ( T ) -> Option < T > ,
73
85
{
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 ) } ) ;
76
95
}
77
96
}
78
97
@@ -98,7 +117,7 @@ impl<T: 'static + Clone> Clone for P<T> {
98
117
99
118
impl < T : ?Sized + Debug > Debug for P < T > {
100
119
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
101
- Debug :: fmt ( & self . ptr , f)
120
+ Debug :: fmt ( & * self . ptr , f)
102
121
}
103
122
}
104
123
@@ -110,7 +129,7 @@ impl<T: Display> Display for P<T> {
110
129
111
130
impl < T > fmt:: Pointer for P < T > {
112
131
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
113
- fmt:: Pointer :: fmt ( & self . ptr , f)
132
+ fmt:: Pointer :: fmt ( & * self . ptr , f)
114
133
}
115
134
}
116
135
@@ -128,17 +147,17 @@ impl<S: Encoder, T: Encodable<S>> Encodable<S> for P<T> {
128
147
129
148
impl < T > P < [ T ] > {
130
149
pub const fn new ( ) -> P < [ T ] > {
131
- P { ptr : Box :: default ( ) }
150
+ P :: from_box ( Box :: default ( ) )
132
151
}
133
152
134
153
#[ inline( never) ]
135
154
pub fn from_vec ( v : Vec < T > ) -> P < [ T ] > {
136
- P { ptr : v. into_boxed_slice ( ) }
155
+ P :: from_box ( v. into_boxed_slice ( ) )
137
156
}
138
157
139
158
#[ inline( never) ]
140
159
pub fn into_vec ( self ) -> Vec < T > {
141
- self . ptr . into_vec ( )
160
+ self . into_box ( ) . into_vec ( )
142
161
}
143
162
}
144
163
0 commit comments