11
11
/** Task-local reference counted smart pointers
12
12
13
13
Task-local reference counted smart pointers are an alternative to managed boxes with deterministic
14
- destruction. They are restricted to containing `Owned` types in order to prevent cycles.
14
+ destruction. They are restricted to containing types that are either `Owned` or `Const` (or both) to
15
+ prevent cycles.
16
+
17
+ Neither `Rc<T>` or `RcMut<T>` is ever `Owned` and `RcMut<T>` is never `Const`. If `T` is `Const`, a
18
+ cycle cannot be created with `Rc<T>` because there is no way to modify it after creation.
15
19
16
20
*/
17
21
@@ -30,16 +34,26 @@ pub struct Rc<T> {
30
34
priv ptr: * mut RcBox < T > ,
31
35
}
32
36
33
- pub impl < T : Owned > Rc < T > {
34
- fn new ( value : T ) -> Rc < T > {
35
- unsafe {
36
- let ptr = malloc ( sys:: size_of :: < RcBox < T > > ( ) as size_t ) as * mut RcBox < T > ;
37
- assert ! ( !ptr:: is_null( ptr) ) ;
38
- intrinsics:: move_val_init ( & mut * ptr, RcBox { value : value, count : 1 } ) ;
39
- Rc { ptr : ptr}
40
- }
37
+ priv impl < T > Rc < T > {
38
+ unsafe fn new ( value : T ) -> Rc < T > {
39
+ let ptr = malloc ( sys:: size_of :: < RcBox < T > > ( ) as size_t ) as * mut RcBox < T > ;
40
+ assert ! ( !ptr:: is_null( ptr) ) ;
41
+ intrinsics:: move_val_init ( & mut * ptr, RcBox { value : value, count : 1 } ) ;
42
+ Rc { ptr : ptr}
41
43
}
44
+ }
45
+
46
+ // FIXME: #6516: should be a static method
47
+ pub fn rc_from_owned < T : Owned > ( value : T ) -> Rc < T > {
48
+ unsafe { Rc :: new ( value) }
49
+ }
50
+
51
+ // FIXME: #6516: should be a static method
52
+ pub fn rc_from_const < T : Const > ( value : T ) -> Rc < T > {
53
+ unsafe { Rc :: new ( value) }
54
+ }
42
55
56
+ pub impl < T > Rc < T > {
43
57
#[ inline( always) ]
44
58
fn borrow < ' r > ( & ' r self ) -> & ' r T {
45
59
unsafe { cast:: copy_lifetime ( self , & ( * self . ptr ) . value ) }
@@ -48,7 +62,7 @@ pub impl<T: Owned> Rc<T> {
48
62
49
63
#[ unsafe_destructor]
50
64
#[ cfg( not( stage0) ) ]
51
- impl < T : Owned > Drop for Rc < T > {
65
+ impl < T > Drop for Rc < T > {
52
66
fn finalize ( & self ) {
53
67
unsafe {
54
68
( * self . ptr ) . count -= 1 ;
@@ -62,7 +76,7 @@ impl<T: Owned> Drop for Rc<T> {
62
76
63
77
#[ unsafe_destructor]
64
78
#[ cfg( stage0) ]
65
- impl < T : Owned > Drop for Rc < T > {
79
+ impl < T > Drop for Rc < T > {
66
80
fn finalize ( & self ) {
67
81
unsafe {
68
82
( * self . ptr ) . count -= 1 ;
@@ -75,7 +89,7 @@ impl<T: Owned> Drop for Rc<T> {
75
89
}
76
90
77
91
78
- impl < T : Owned > Clone for Rc < T > {
92
+ impl < T > Clone for Rc < T > {
79
93
/// Return a shallow copy of the reference counted pointer.
80
94
#[ inline]
81
95
fn clone ( & self ) -> Rc < T > {
@@ -86,11 +100,11 @@ impl<T: Owned> Clone for Rc<T> {
86
100
}
87
101
}
88
102
89
- impl < T : Owned + DeepClone > DeepClone for Rc < T > {
103
+ impl < T : DeepClone > DeepClone for Rc < T > {
90
104
/// Return a deep copy of the reference counted pointer.
91
105
#[ inline]
92
106
fn deep_clone ( & self ) -> Rc < T > {
93
- Rc :: new ( self . borrow ( ) . deep_clone ( ) )
107
+ unsafe { Rc :: new ( self . borrow ( ) . deep_clone ( ) ) }
94
108
}
95
109
}
96
110
@@ -101,7 +115,7 @@ mod test_rc {
101
115
102
116
#[ test]
103
117
fn test_clone( ) {
104
- let x = Rc :: new ( Cell ( 5 ) ) ;
118
+ let x = rc_from_owned ( Cell ( 5 ) ) ;
105
119
let y = x. clone ( ) ;
106
120
do x. borrow ( ) . with_mut_ref |inner| {
107
121
* inner = 20 ;
@@ -111,7 +125,7 @@ mod test_rc {
111
125
112
126
#[ test]
113
127
fn test_deep_clone( ) {
114
- let x = Rc :: new ( Cell ( 5 ) ) ;
128
+ let x = rc_from_owned ( Cell ( 5 ) ) ;
115
129
let y = x. deep_clone ( ) ;
116
130
do x. borrow ( ) . with_mut_ref |inner| {
117
131
* inner = 20 ;
@@ -121,21 +135,21 @@ mod test_rc {
121
135
122
136
#[ test]
123
137
fn test_simple ( ) {
124
- let x = Rc :: new ( 5 ) ;
138
+ let x = rc_from_const ( 5 ) ;
125
139
assert_eq ! ( * x. borrow( ) , 5 ) ;
126
140
}
127
141
128
142
#[ test]
129
143
fn test_simple_clone ( ) {
130
- let x = Rc :: new ( 5 ) ;
144
+ let x = rc_from_const ( 5 ) ;
131
145
let y = x. clone ( ) ;
132
146
assert_eq ! ( * x. borrow( ) , 5 ) ;
133
147
assert_eq ! ( * y. borrow( ) , 5 ) ;
134
148
}
135
149
136
150
#[ test]
137
151
fn test_destructor ( ) {
138
- let x = Rc :: new ( ~5 ) ;
152
+ let x = rc_from_owned ( ~5 ) ;
139
153
assert_eq ! ( * * x. borrow( ) , 5 ) ;
140
154
}
141
155
}
@@ -167,16 +181,26 @@ pub struct RcMut<T> {
167
181
priv ptr: * mut RcMutBox < T > ,
168
182
}
169
183
170
- pub impl < T : Owned > RcMut < T > {
171
- fn new ( value : T ) -> RcMut < T > {
172
- unsafe {
173
- let ptr = malloc ( sys:: size_of :: < RcMutBox < T > > ( ) as size_t ) as * mut RcMutBox < T > ;
174
- assert ! ( !ptr:: is_null( ptr) ) ;
175
- intrinsics:: move_val_init ( & mut * ptr, RcMutBox { value : value, count : 1 , borrow : Nothing } ) ;
176
- RcMut { ptr : ptr}
177
- }
184
+ priv impl < T > RcMut < T > {
185
+ unsafe fn new ( value : T ) -> RcMut < T > {
186
+ let ptr = malloc ( sys:: size_of :: < RcMutBox < T > > ( ) as size_t ) as * mut RcMutBox < T > ;
187
+ assert ! ( !ptr:: is_null( ptr) ) ;
188
+ intrinsics:: move_val_init ( & mut * ptr, RcMutBox { value : value, count : 1 , borrow : Nothing } ) ;
189
+ RcMut { ptr : ptr}
178
190
}
191
+ }
192
+
193
+ // FIXME: #6516: should be a static method
194
+ pub fn rc_mut_from_owned < T : Owned > ( value : T ) -> RcMut < T > {
195
+ unsafe { RcMut :: new ( value) }
196
+ }
197
+
198
+ // FIXME: #6516: should be a static method
199
+ pub fn rc_mut_from_const < T : Const > ( value : T ) -> RcMut < T > {
200
+ unsafe { RcMut :: new ( value) }
201
+ }
179
202
203
+ pub impl < T > RcMut < T > {
180
204
/// Fails if there is already a mutable borrow of the box
181
205
#[ inline]
182
206
fn with_borrow < U > ( & self , f : & fn ( & T ) -> U ) -> U {
@@ -205,7 +229,7 @@ pub impl<T: Owned> RcMut<T> {
205
229
206
230
#[ unsafe_destructor]
207
231
#[ cfg( not( stage0) ) ]
208
- impl < T : Owned > Drop for RcMut < T > {
232
+ impl < T > Drop for RcMut < T > {
209
233
fn finalize ( & self ) {
210
234
unsafe {
211
235
( * self . ptr ) . count -= 1 ;
@@ -219,7 +243,7 @@ impl<T: Owned> Drop for RcMut<T> {
219
243
220
244
#[ unsafe_destructor]
221
245
#[ cfg( stage0) ]
222
- impl < T : Owned > Drop for RcMut < T > {
246
+ impl < T > Drop for RcMut < T > {
223
247
fn finalize ( & self ) {
224
248
unsafe {
225
249
( * self . ptr ) . count -= 1 ;
@@ -231,7 +255,7 @@ impl<T: Owned> Drop for RcMut<T> {
231
255
}
232
256
}
233
257
234
- impl < T : Owned > Clone for RcMut < T > {
258
+ impl < T > Clone for RcMut < T > {
235
259
/// Return a shallow copy of the reference counted pointer.
236
260
#[ inline]
237
261
fn clone ( & self ) -> RcMut < T > {
@@ -242,13 +266,13 @@ impl<T: Owned> Clone for RcMut<T> {
242
266
}
243
267
}
244
268
245
- impl < T : Owned + DeepClone > DeepClone for RcMut < T > {
269
+ impl < T : DeepClone > DeepClone for RcMut < T > {
246
270
/// Return a deep copy of the reference counted pointer.
247
271
#[ inline]
248
272
fn deep_clone ( & self ) -> RcMut < T > {
249
273
do self . with_borrow |x| {
250
274
// FIXME: #6497: should avoid freeze (slow)
251
- RcMut :: new ( x. deep_clone ( ) )
275
+ unsafe { RcMut :: new ( x. deep_clone ( ) ) }
252
276
}
253
277
}
254
278
}
@@ -259,7 +283,7 @@ mod test_rc_mut {
259
283
260
284
#[ test]
261
285
fn test_clone ( ) {
262
- let x = RcMut :: new ( 5 ) ;
286
+ let x = rc_mut_from_owned ( 5 ) ;
263
287
let y = x. clone ( ) ;
264
288
do x. with_mut_borrow |value| {
265
289
* value = 20 ;
@@ -271,7 +295,7 @@ mod test_rc_mut {
271
295
272
296
#[ test]
273
297
fn test_deep_clone ( ) {
274
- let x = RcMut :: new ( 5 ) ;
298
+ let x = rc_mut_from_const ( 5 ) ;
275
299
let y = x. deep_clone ( ) ;
276
300
do x. with_mut_borrow |value| {
277
301
* value = 20 ;
@@ -283,7 +307,7 @@ mod test_rc_mut {
283
307
284
308
#[ test]
285
309
fn borrow_many ( ) {
286
- let x = RcMut :: new ( 5 ) ;
310
+ let x = rc_mut_from_owned ( 5 ) ;
287
311
let y = x. clone ( ) ;
288
312
289
313
do x. with_borrow |a| {
@@ -299,7 +323,7 @@ mod test_rc_mut {
299
323
300
324
#[ test]
301
325
fn modify ( ) {
302
- let x = RcMut :: new ( 5 ) ;
326
+ let x = rc_mut_from_const ( 5 ) ;
303
327
let y = x. clone ( ) ;
304
328
305
329
do y. with_mut_borrow |a| {
@@ -314,22 +338,22 @@ mod test_rc_mut {
314
338
315
339
#[ test]
316
340
fn release_immutable ( ) {
317
- let x = RcMut :: new ( 5 ) ;
341
+ let x = rc_mut_from_owned ( 5 ) ;
318
342
do x. with_borrow |_| { }
319
343
do x. with_mut_borrow |_| { }
320
344
}
321
345
322
346
#[ test]
323
347
fn release_mutable ( ) {
324
- let x = RcMut :: new ( 5 ) ;
348
+ let x = rc_mut_from_const ( 5 ) ;
325
349
do x. with_mut_borrow |_| { }
326
350
do x. with_borrow |_| { }
327
351
}
328
352
329
353
#[ test]
330
354
#[ should_fail]
331
355
fn frozen ( ) {
332
- let x = RcMut :: new ( 5 ) ;
356
+ let x = rc_mut_from_owned ( 5 ) ;
333
357
let y = x. clone ( ) ;
334
358
335
359
do x. with_borrow |_| {
@@ -341,7 +365,7 @@ mod test_rc_mut {
341
365
#[ test]
342
366
#[ should_fail]
343
367
fn mutable_dupe ( ) {
344
- let x = RcMut :: new ( 5 ) ;
368
+ let x = rc_mut_from_const ( 5 ) ;
345
369
let y = x. clone ( ) ;
346
370
347
371
do x. with_mut_borrow |_| {
@@ -353,7 +377,7 @@ mod test_rc_mut {
353
377
#[ test]
354
378
#[ should_fail]
355
379
fn mutable_freeze ( ) {
356
- let x = RcMut :: new ( 5 ) ;
380
+ let x = rc_mut_from_owned ( 5 ) ;
357
381
let y = x. clone ( ) ;
358
382
359
383
do x. with_mut_borrow |_| {
@@ -365,7 +389,7 @@ mod test_rc_mut {
365
389
#[ test]
366
390
#[ should_fail]
367
391
fn restore_freeze ( ) {
368
- let x = RcMut :: new ( 5 ) ;
392
+ let x = rc_mut_from_const ( 5 ) ;
369
393
let y = x. clone ( ) ;
370
394
371
395
do x. with_borrow |_| {
0 commit comments