Skip to content

Commit 4702667

Browse files
committed
allow constructing Rc/RcMut from Const types too
1 parent 8a15333 commit 4702667

File tree

1 file changed

+66
-42
lines changed

1 file changed

+66
-42
lines changed

src/libstd/rc.rs

+66-42
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
/** Task-local reference counted smart pointers
1212
1313
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.
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

Comments
 (0)