1111/** Task-local reference counted smart pointers
1212
1313Task-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.
1519
1620*/
1721
@@ -30,16 +34,26 @@ pub struct Rc<T> {
3034 priv ptr: * mut RcBox < T > ,
3135}
3236
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}
4143 }
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+ }
4255
56+ pub impl < T > Rc < T > {
4357 #[ inline( always) ]
4458 fn borrow < ' r > ( & ' r self ) -> & ' r T {
4559 unsafe { cast:: copy_lifetime ( self , & ( * self . ptr ) . value ) }
@@ -48,7 +62,7 @@ pub impl<T: Owned> Rc<T> {
4862
4963#[ unsafe_destructor]
5064#[ cfg( not( stage0) ) ]
51- impl < T : Owned > Drop for Rc < T > {
65+ impl < T > Drop for Rc < T > {
5266 fn finalize ( & self ) {
5367 unsafe {
5468 ( * self . ptr ) . count -= 1 ;
@@ -62,7 +76,7 @@ impl<T: Owned> Drop for Rc<T> {
6276
6377#[ unsafe_destructor]
6478#[ cfg( stage0) ]
65- impl < T : Owned > Drop for Rc < T > {
79+ impl < T > Drop for Rc < T > {
6680 fn finalize ( & self ) {
6781 unsafe {
6882 ( * self . ptr ) . count -= 1 ;
@@ -75,7 +89,7 @@ impl<T: Owned> Drop for Rc<T> {
7589}
7690
7791
78- impl < T : Owned > Clone for Rc < T > {
92+ impl < T > Clone for Rc < T > {
7993 /// Return a shallow copy of the reference counted pointer.
8094 #[ inline]
8195 fn clone ( & self ) -> Rc < T > {
@@ -86,11 +100,11 @@ impl<T: Owned> Clone for Rc<T> {
86100 }
87101}
88102
89- impl < T : Owned + DeepClone > DeepClone for Rc < T > {
103+ impl < T : DeepClone > DeepClone for Rc < T > {
90104 /// Return a deep copy of the reference counted pointer.
91105 #[ inline]
92106 fn deep_clone ( & self ) -> Rc < T > {
93- Rc :: new ( self . borrow ( ) . deep_clone ( ) )
107+ unsafe { Rc :: new ( self . borrow ( ) . deep_clone ( ) ) }
94108 }
95109}
96110
@@ -101,7 +115,7 @@ mod test_rc {
101115
102116 #[ test]
103117 fn test_clone( ) {
104- let x = Rc :: new ( Cell ( 5 ) ) ;
118+ let x = rc_from_owned ( Cell ( 5 ) ) ;
105119 let y = x. clone ( ) ;
106120 do x. borrow ( ) . with_mut_ref |inner| {
107121 * inner = 20 ;
@@ -111,7 +125,7 @@ mod test_rc {
111125
112126 #[ test]
113127 fn test_deep_clone( ) {
114- let x = Rc :: new ( Cell ( 5 ) ) ;
128+ let x = rc_from_owned ( Cell ( 5 ) ) ;
115129 let y = x. deep_clone ( ) ;
116130 do x. borrow ( ) . with_mut_ref |inner| {
117131 * inner = 20 ;
@@ -121,21 +135,21 @@ mod test_rc {
121135
122136 #[ test]
123137 fn test_simple ( ) {
124- let x = Rc :: new ( 5 ) ;
138+ let x = rc_from_const ( 5 ) ;
125139 assert_eq ! ( * x. borrow( ) , 5 ) ;
126140 }
127141
128142 #[ test]
129143 fn test_simple_clone ( ) {
130- let x = Rc :: new ( 5 ) ;
144+ let x = rc_from_const ( 5 ) ;
131145 let y = x. clone ( ) ;
132146 assert_eq ! ( * x. borrow( ) , 5 ) ;
133147 assert_eq ! ( * y. borrow( ) , 5 ) ;
134148 }
135149
136150 #[ test]
137151 fn test_destructor ( ) {
138- let x = Rc :: new ( ~5 ) ;
152+ let x = rc_from_owned ( ~5 ) ;
139153 assert_eq ! ( * * x. borrow( ) , 5 ) ;
140154 }
141155}
@@ -167,16 +181,26 @@ pub struct RcMut<T> {
167181 priv ptr: * mut RcMutBox < T > ,
168182}
169183
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}
178190 }
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+ }
179202
203+ pub impl < T > RcMut < T > {
180204 /// Fails if there is already a mutable borrow of the box
181205 #[ inline]
182206 fn with_borrow < U > ( & self , f : & fn ( & T ) -> U ) -> U {
@@ -205,7 +229,7 @@ pub impl<T: Owned> RcMut<T> {
205229
206230#[ unsafe_destructor]
207231#[ cfg( not( stage0) ) ]
208- impl < T : Owned > Drop for RcMut < T > {
232+ impl < T > Drop for RcMut < T > {
209233 fn finalize ( & self ) {
210234 unsafe {
211235 ( * self . ptr ) . count -= 1 ;
@@ -219,7 +243,7 @@ impl<T: Owned> Drop for RcMut<T> {
219243
220244#[ unsafe_destructor]
221245#[ cfg( stage0) ]
222- impl < T : Owned > Drop for RcMut < T > {
246+ impl < T > Drop for RcMut < T > {
223247 fn finalize ( & self ) {
224248 unsafe {
225249 ( * self . ptr ) . count -= 1 ;
@@ -231,7 +255,7 @@ impl<T: Owned> Drop for RcMut<T> {
231255 }
232256}
233257
234- impl < T : Owned > Clone for RcMut < T > {
258+ impl < T > Clone for RcMut < T > {
235259 /// Return a shallow copy of the reference counted pointer.
236260 #[ inline]
237261 fn clone ( & self ) -> RcMut < T > {
@@ -242,13 +266,13 @@ impl<T: Owned> Clone for RcMut<T> {
242266 }
243267}
244268
245- impl < T : Owned + DeepClone > DeepClone for RcMut < T > {
269+ impl < T : DeepClone > DeepClone for RcMut < T > {
246270 /// Return a deep copy of the reference counted pointer.
247271 #[ inline]
248272 fn deep_clone ( & self ) -> RcMut < T > {
249273 do self . with_borrow |x| {
250274 // FIXME: #6497: should avoid freeze (slow)
251- RcMut :: new ( x. deep_clone ( ) )
275+ unsafe { RcMut :: new ( x. deep_clone ( ) ) }
252276 }
253277 }
254278}
@@ -259,7 +283,7 @@ mod test_rc_mut {
259283
260284 #[ test]
261285 fn test_clone ( ) {
262- let x = RcMut :: new ( 5 ) ;
286+ let x = rc_mut_from_owned ( 5 ) ;
263287 let y = x. clone ( ) ;
264288 do x. with_mut_borrow |value| {
265289 * value = 20 ;
@@ -271,7 +295,7 @@ mod test_rc_mut {
271295
272296 #[ test]
273297 fn test_deep_clone ( ) {
274- let x = RcMut :: new ( 5 ) ;
298+ let x = rc_mut_from_const ( 5 ) ;
275299 let y = x. deep_clone ( ) ;
276300 do x. with_mut_borrow |value| {
277301 * value = 20 ;
@@ -283,7 +307,7 @@ mod test_rc_mut {
283307
284308 #[ test]
285309 fn borrow_many ( ) {
286- let x = RcMut :: new ( 5 ) ;
310+ let x = rc_mut_from_owned ( 5 ) ;
287311 let y = x. clone ( ) ;
288312
289313 do x. with_borrow |a| {
@@ -299,7 +323,7 @@ mod test_rc_mut {
299323
300324 #[ test]
301325 fn modify ( ) {
302- let x = RcMut :: new ( 5 ) ;
326+ let x = rc_mut_from_const ( 5 ) ;
303327 let y = x. clone ( ) ;
304328
305329 do y. with_mut_borrow |a| {
@@ -314,22 +338,22 @@ mod test_rc_mut {
314338
315339 #[ test]
316340 fn release_immutable ( ) {
317- let x = RcMut :: new ( 5 ) ;
341+ let x = rc_mut_from_owned ( 5 ) ;
318342 do x. with_borrow |_| { }
319343 do x. with_mut_borrow |_| { }
320344 }
321345
322346 #[ test]
323347 fn release_mutable ( ) {
324- let x = RcMut :: new ( 5 ) ;
348+ let x = rc_mut_from_const ( 5 ) ;
325349 do x. with_mut_borrow |_| { }
326350 do x. with_borrow |_| { }
327351 }
328352
329353 #[ test]
330354 #[ should_fail]
331355 fn frozen ( ) {
332- let x = RcMut :: new ( 5 ) ;
356+ let x = rc_mut_from_owned ( 5 ) ;
333357 let y = x. clone ( ) ;
334358
335359 do x. with_borrow |_| {
@@ -341,7 +365,7 @@ mod test_rc_mut {
341365 #[ test]
342366 #[ should_fail]
343367 fn mutable_dupe ( ) {
344- let x = RcMut :: new ( 5 ) ;
368+ let x = rc_mut_from_const ( 5 ) ;
345369 let y = x. clone ( ) ;
346370
347371 do x. with_mut_borrow |_| {
@@ -353,7 +377,7 @@ mod test_rc_mut {
353377 #[ test]
354378 #[ should_fail]
355379 fn mutable_freeze ( ) {
356- let x = RcMut :: new ( 5 ) ;
380+ let x = rc_mut_from_owned ( 5 ) ;
357381 let y = x. clone ( ) ;
358382
359383 do x. with_mut_borrow |_| {
@@ -365,7 +389,7 @@ mod test_rc_mut {
365389 #[ test]
366390 #[ should_fail]
367391 fn restore_freeze ( ) {
368- let x = RcMut :: new ( 5 ) ;
392+ let x = rc_mut_from_const ( 5 ) ;
369393 let y = x. clone ( ) ;
370394
371395 do x. with_borrow |_| {
0 commit comments