Skip to content

Commit 8f86fa3

Browse files
blake2-ppcthestinger
blake2-ppc
authored andcommitted
rc: Use ~T for allocation
Simplify Rc<T>/RcMut<T> by using ~T when allocating a reference counted box.
1 parent 4a2d22b commit 8f86fa3

File tree

2 files changed

+44
-48
lines changed

2 files changed

+44
-48
lines changed

src/libextra/rc.rs

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,17 @@ cycle cannot be created with `Rc<T>` because there is no way to modify it after
2323

2424

2525
use std::cast;
26-
use std::libc::{c_void, size_t, malloc, free};
2726
use std::ptr;
28-
use std::sys;
2927
use std::unstable::intrinsics;
3028

29+
// Convert ~T into *mut T without dropping it
30+
#[inline]
31+
unsafe fn owned_to_raw<T>(mut box: ~T) -> *mut T {
32+
let ptr = ptr::to_mut_unsafe_ptr(box);
33+
intrinsics::forget(box);
34+
ptr
35+
}
36+
3137
struct RcBox<T> {
3238
value: T,
3339
count: uint
@@ -42,21 +48,20 @@ pub struct Rc<T> {
4248

4349
impl<T> Rc<T> {
4450
unsafe fn new(value: T) -> Rc<T> {
45-
let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>;
46-
assert!(!ptr::is_null(ptr));
47-
intrinsics::move_val_init(&mut *ptr, RcBox{value: value, count: 1});
48-
Rc{ptr: ptr}
51+
Rc{ptr: owned_to_raw(~RcBox{value: value, count: 1})}
4952
}
5053
}
5154

52-
// FIXME: #6516: should be a static method
53-
pub fn rc_from_owned<T: Send>(value: T) -> Rc<T> {
54-
unsafe { Rc::new(value) }
55+
impl<T: Send> Rc<T> {
56+
pub fn from_owned(value: T) -> Rc<T> {
57+
unsafe { Rc::new(value) }
58+
}
5559
}
5660

57-
// FIXME: #6516: should be a static method
58-
pub fn rc_from_const<T: Freeze>(value: T) -> Rc<T> {
59-
unsafe { Rc::new(value) }
61+
impl<T: Freeze> Rc<T> {
62+
pub fn from_const(value: T) -> Rc<T> {
63+
unsafe { Rc::new(value) }
64+
}
6065
}
6166

6267
impl<T> Rc<T> {
@@ -73,8 +78,7 @@ impl<T> Drop for Rc<T> {
7378
if self.ptr.is_not_null() {
7479
(*self.ptr).count -= 1;
7580
if (*self.ptr).count == 0 {
76-
ptr::read_ptr(self.ptr);
77-
free(self.ptr as *c_void)
81+
let _: ~T = cast::transmute(self.ptr);
7882
}
7983
}
8084
}
@@ -107,7 +111,7 @@ mod test_rc {
107111

108112
#[test]
109113
fn test_clone() {
110-
let x = rc_from_owned(Cell::new(5));
114+
let x = Rc::from_owned(Cell::new(5));
111115
let y = x.clone();
112116
do x.borrow().with_mut_ref |inner| {
113117
*inner = 20;
@@ -117,7 +121,7 @@ mod test_rc {
117121

118122
#[test]
119123
fn test_deep_clone() {
120-
let x = rc_from_owned(Cell::new(5));
124+
let x = Rc::from_owned(Cell::new(5));
121125
let y = x.deep_clone();
122126
do x.borrow().with_mut_ref |inner| {
123127
*inner = 20;
@@ -127,31 +131,25 @@ mod test_rc {
127131

128132
#[test]
129133
fn test_simple() {
130-
let x = rc_from_const(5);
134+
let x = Rc::from_const(5);
131135
assert_eq!(*x.borrow(), 5);
132136
}
133137

134138
#[test]
135139
fn test_simple_clone() {
136-
let x = rc_from_const(5);
140+
let x = Rc::from_const(5);
137141
let y = x.clone();
138142
assert_eq!(*x.borrow(), 5);
139143
assert_eq!(*y.borrow(), 5);
140144
}
141145

142146
#[test]
143147
fn test_destructor() {
144-
let x = rc_from_owned(~5);
148+
let x = Rc::from_owned(~5);
145149
assert_eq!(**x.borrow(), 5);
146150
}
147151
}
148152

149-
#[abi = "rust-intrinsic"]
150-
extern "rust-intrinsic" {
151-
fn init<T>() -> T;
152-
fn uninit<T>() -> T;
153-
}
154-
155153
#[deriving(Eq)]
156154
enum Borrow {
157155
Mutable,
@@ -175,21 +173,20 @@ pub struct RcMut<T> {
175173

176174
impl<T> RcMut<T> {
177175
unsafe fn new(value: T) -> RcMut<T> {
178-
let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>;
179-
assert!(!ptr::is_null(ptr));
180-
intrinsics::move_val_init(&mut *ptr, RcMutBox{value: value, count: 1, borrow: Nothing});
181-
RcMut{ptr: ptr}
176+
RcMut{ptr: owned_to_raw(~RcMutBox{value: value, count: 1, borrow: Nothing})}
182177
}
183178
}
184179

185-
// FIXME: #6516: should be a static method
186-
pub fn rc_mut_from_owned<T: Send>(value: T) -> RcMut<T> {
187-
unsafe { RcMut::new(value) }
180+
impl<T: Send> RcMut<T> {
181+
pub fn from_owned(value: T) -> RcMut<T> {
182+
unsafe { RcMut::new(value) }
183+
}
188184
}
189185

190-
// FIXME: #6516: should be a static method
191-
pub fn rc_mut_from_const<T: Freeze>(value: T) -> RcMut<T> {
192-
unsafe { RcMut::new(value) }
186+
impl<T: Freeze> RcMut<T> {
187+
pub fn from_const(value: T) -> RcMut<T> {
188+
unsafe { RcMut::new(value) }
189+
}
193190
}
194191

195192
impl<T> RcMut<T> {
@@ -226,8 +223,7 @@ impl<T> Drop for RcMut<T> {
226223
if self.ptr.is_not_null() {
227224
(*self.ptr).count -= 1;
228225
if (*self.ptr).count == 0 {
229-
ptr::replace_ptr(self.ptr, uninit());
230-
free(self.ptr as *c_void)
226+
let _: ~T = cast::transmute(self.ptr);
231227
}
232228
}
233229
}
@@ -262,7 +258,7 @@ mod test_rc_mut {
262258

263259
#[test]
264260
fn test_clone() {
265-
let x = rc_mut_from_owned(5);
261+
let x = RcMut::from_owned(5);
266262
let y = x.clone();
267263
do x.with_mut_borrow |value| {
268264
*value = 20;
@@ -274,7 +270,7 @@ mod test_rc_mut {
274270

275271
#[test]
276272
fn test_deep_clone() {
277-
let x = rc_mut_from_const(5);
273+
let x = RcMut::from_const(5);
278274
let y = x.deep_clone();
279275
do x.with_mut_borrow |value| {
280276
*value = 20;
@@ -286,7 +282,7 @@ mod test_rc_mut {
286282

287283
#[test]
288284
fn borrow_many() {
289-
let x = rc_mut_from_owned(5);
285+
let x = RcMut::from_owned(5);
290286
let y = x.clone();
291287

292288
do x.with_borrow |a| {
@@ -302,7 +298,7 @@ mod test_rc_mut {
302298

303299
#[test]
304300
fn modify() {
305-
let x = rc_mut_from_const(5);
301+
let x = RcMut::from_const(5);
306302
let y = x.clone();
307303

308304
do y.with_mut_borrow |a| {
@@ -317,22 +313,22 @@ mod test_rc_mut {
317313

318314
#[test]
319315
fn release_immutable() {
320-
let x = rc_mut_from_owned(5);
316+
let x = RcMut::from_owned(5);
321317
do x.with_borrow |_| {}
322318
do x.with_mut_borrow |_| {}
323319
}
324320

325321
#[test]
326322
fn release_mutable() {
327-
let x = rc_mut_from_const(5);
323+
let x = RcMut::from_const(5);
328324
do x.with_mut_borrow |_| {}
329325
do x.with_borrow |_| {}
330326
}
331327

332328
#[test]
333329
#[should_fail]
334330
fn frozen() {
335-
let x = rc_mut_from_owned(5);
331+
let x = RcMut::from_owned(5);
336332
let y = x.clone();
337333

338334
do x.with_borrow |_| {
@@ -344,7 +340,7 @@ mod test_rc_mut {
344340
#[test]
345341
#[should_fail]
346342
fn mutable_dupe() {
347-
let x = rc_mut_from_const(5);
343+
let x = RcMut::from_const(5);
348344
let y = x.clone();
349345

350346
do x.with_mut_borrow |_| {
@@ -356,7 +352,7 @@ mod test_rc_mut {
356352
#[test]
357353
#[should_fail]
358354
fn mutable_freeze() {
359-
let x = rc_mut_from_owned(5);
355+
let x = RcMut::from_owned(5);
360356
let y = x.clone();
361357

362358
do x.with_mut_borrow |_| {
@@ -368,7 +364,7 @@ mod test_rc_mut {
368364
#[test]
369365
#[should_fail]
370366
fn restore_freeze() {
371-
let x = rc_mut_from_const(5);
367+
let x = RcMut::from_const(5);
372368
let y = x.clone();
373369

374370
do x.with_borrow |_| {

src/test/compile-fail/rcmut-not-const-and-not-owned.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn o<T: Send>(_: &T) {}
1414
fn c<T: Freeze>(_: &T) {}
1515

1616
fn main() {
17-
let x = extra::rc::rc_mut_from_owned(0);
17+
let x = extra::rc::RcMut::from_owned(0);
1818
o(&x); //~ ERROR instantiating a type parameter with an incompatible type `extra::rc::RcMut<int>`, which does not fulfill `Send`
1919
c(&x); //~ ERROR instantiating a type parameter with an incompatible type `extra::rc::RcMut<int>`, which does not fulfill `Freeze`
2020
}

0 commit comments

Comments
 (0)