@@ -33,40 +33,42 @@ use std::{mem, ptr, slice, vec};
33
33
34
34
use serialize:: { Encodable , Decodable , Encoder , Decoder } ;
35
35
36
+ use rustc_data_structures:: sync:: Lrc ;
36
37
use rustc_data_structures:: stable_hasher:: { StableHasher , StableHasherResult ,
37
38
HashStable } ;
38
39
/// An owned smart pointer.
39
40
#[ derive( Hash , PartialEq , Eq ) ]
40
41
pub struct P < T : ?Sized > {
41
- ptr : Box < T >
42
+ ptr : Lrc < T >
42
43
}
43
44
44
45
#[ allow( non_snake_case) ]
45
46
/// Construct a `P<T>` from a `T` value.
46
47
pub fn P < T : ' static > ( value : T ) -> P < T > {
47
48
P {
48
- ptr : Box :: new ( value)
49
+ ptr : Lrc :: new ( value)
49
50
}
50
51
}
51
52
52
- impl < T : ' static > P < T > {
53
+ impl < T : ' static + Clone > P < T > {
53
54
/// Move out of the pointer.
54
55
/// Intended for chaining transformations not covered by `map`.
55
56
pub fn and_then < U , F > ( self , f : F ) -> U where
56
57
F : FnOnce ( T ) -> U ,
57
58
{
58
- f ( * self . ptr )
59
+ f ( self . into_inner ( ) )
59
60
}
60
61
/// Equivalent to and_then(|x| x)
61
62
pub fn into_inner ( self ) -> T {
62
- * self . ptr
63
+ Lrc :: try_unwrap ( self . ptr ) . unwrap_or_else ( |ptr| ( * ptr ) . clone ( ) )
63
64
}
64
65
65
66
/// Produce a new `P<T>` from `self` without reallocating.
66
67
pub fn map < F > ( mut self , f : F ) -> P < T > where
67
68
F : FnOnce ( T ) -> T ,
68
69
{
69
- let p: * mut T = & mut * self . ptr ;
70
+ // FIXME(eddyb) How can we reuse the original if unchanged?
71
+ let p: * mut T = Lrc :: make_mut ( & mut self . ptr ) ;
70
72
71
73
// Leak self in case of panic.
72
74
// FIXME(eddyb) Use some sort of "free guard" that
@@ -78,15 +80,16 @@ impl<T: 'static> P<T> {
78
80
ptr:: write ( p, f ( ptr:: read ( p) ) ) ;
79
81
80
82
// Recreate self from the raw pointer.
81
- P { ptr : Box :: from_raw ( p) }
83
+ P { ptr : Lrc :: from_raw ( p) }
82
84
}
83
85
}
84
86
85
87
/// Optionally produce a new `P<T>` from `self` without reallocating.
86
88
pub fn filter_map < F > ( mut self , f : F ) -> Option < P < T > > where
87
89
F : FnOnce ( T ) -> Option < T > ,
88
90
{
89
- let p: * mut T = & mut * self . ptr ;
91
+ // FIXME(eddyb) How can we reuse the original if unchanged?
92
+ let p: * mut T = Lrc :: make_mut ( & mut self . ptr ) ;
90
93
91
94
// Leak self in case of panic.
92
95
// FIXME(eddyb) Use some sort of "free guard" that
@@ -99,9 +102,9 @@ impl<T: 'static> P<T> {
99
102
ptr:: write ( p, v) ;
100
103
101
104
// Recreate self from the raw pointer.
102
- Some ( P { ptr : Box :: from_raw ( p) } )
105
+ Some ( P { ptr : Lrc :: from_raw ( p) } )
103
106
} else {
104
- drop ( Box :: from_raw ( p) ) ;
107
+ drop ( Lrc :: from_raw ( p) ) ;
105
108
None
106
109
}
107
110
}
@@ -116,15 +119,17 @@ impl<T: ?Sized> Deref for P<T> {
116
119
}
117
120
}
118
121
119
- impl < T : ? Sized > DerefMut for P < T > {
122
+ impl < T : Clone > DerefMut for P < T > {
120
123
fn deref_mut ( & mut self ) -> & mut T {
121
- & mut self . ptr
124
+ Lrc :: make_mut ( & mut self . ptr )
122
125
}
123
126
}
124
127
125
- impl < T : ' static + Clone > Clone for P < T > {
128
+ impl < T : ? Sized > Clone for P < T > {
126
129
fn clone ( & self ) -> P < T > {
127
- P ( ( * * self ) . clone ( ) )
130
+ P {
131
+ ptr : self . ptr . clone ( ) ,
132
+ }
128
133
}
129
134
}
130
135
@@ -160,17 +165,21 @@ impl<T: Encodable> Encodable for P<T> {
160
165
161
166
impl < T > P < [ T ] > {
162
167
pub fn new ( ) -> P < [ T ] > {
163
- P { ptr : Default :: default ( ) }
168
+ P { ptr : Lrc :: new ( [ ] ) }
164
169
}
165
170
171
+ // FIXME(eddyb) this is inefficient because it needs to
172
+ // move all the elements to accomodate `Lrc`'s allocation.
166
173
#[ inline( never) ]
167
174
pub fn from_vec ( v : Vec < T > ) -> P < [ T ] > {
168
- P { ptr : v. into_boxed_slice ( ) }
175
+ P { ptr : v. into ( ) }
169
176
}
170
177
178
+ // FIXME(eddyb) this is inefficient because it needs to
179
+ // clone all the elements out of the `Lrc<[T]>`.
171
180
#[ inline( never) ]
172
- pub fn into_vec ( self ) -> Vec < T > {
173
- self . ptr . into_vec ( )
181
+ pub fn into_vec ( self ) -> Vec < T > where T : Clone {
182
+ self . ptr . to_vec ( )
174
183
}
175
184
}
176
185
@@ -181,31 +190,41 @@ impl<T> Default for P<[T]> {
181
190
}
182
191
}
183
192
184
- impl < T : Clone > Clone for P < [ T ] > {
185
- fn clone ( & self ) -> P < [ T ] > {
186
- P :: from_vec ( self . to_vec ( ) )
187
- }
188
- }
189
-
190
193
impl < T > From < Vec < T > > for P < [ T ] > {
191
194
fn from ( v : Vec < T > ) -> Self {
192
195
P :: from_vec ( v)
193
196
}
194
197
}
195
198
196
- impl < T > Into < Vec < T > > for P < [ T ] > {
199
+ // FIXME(eddyb) this is inefficient because it needs to
200
+ // clone all the elements out of the `Lrc<[T]>`.
201
+ impl < T : Clone > Into < Vec < T > > for P < [ T ] > {
197
202
fn into ( self ) -> Vec < T > {
198
203
self . into_vec ( )
199
204
}
200
205
}
201
206
207
+ // FIXME(eddyb) this is inefficient because it needs to
208
+ // clone all the elements out of the `Lrc<[T]>`.
209
+ impl < T : Clone > DerefMut for P < [ T ] > {
210
+ fn deref_mut ( & mut self ) -> & mut [ T ] {
211
+ // HACK(eddyb) this emulates `make_mut` for `Lrc<[T]>`.
212
+ if Lrc :: get_mut ( & mut self . ptr ) . is_none ( ) {
213
+ self . ptr = self . ptr . to_vec ( ) . into ( ) ;
214
+ }
215
+ Lrc :: get_mut ( & mut self . ptr ) . unwrap ( )
216
+ }
217
+ }
218
+
202
219
impl < T > FromIterator < T > for P < [ T ] > {
203
220
fn from_iter < I : IntoIterator < Item =T > > ( iter : I ) -> P < [ T ] > {
204
221
P :: from_vec ( iter. into_iter ( ) . collect ( ) )
205
222
}
206
223
}
207
224
208
- impl < T > IntoIterator for P < [ T ] > {
225
+ // FIXME(eddyb) this is inefficient because it needs to
226
+ // clone all the elements out of the `Lrc<[T]>`.
227
+ impl < T : Clone > IntoIterator for P < [ T ] > {
209
228
type Item = T ;
210
229
type IntoIter = vec:: IntoIter < T > ;
211
230
0 commit comments