Skip to content

Commit 98fdf0f

Browse files
committed
liballoc: Use NonZero in Rc.
1 parent 652b793 commit 98fdf0f

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

src/liballoc/rc.rs

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,7 @@ use core::mem::{transmute, min_align_of, size_of, forget};
151151
use core::ops::{Deref, Drop};
152152
use core::option::Option;
153153
use core::option::Option::{Some, None};
154-
use core::ptr;
155-
use core::ptr::RawPtr;
154+
use core::ptr::{mod, NonZero, RawPtr};
156155
use core::result::Result;
157156
use core::result::Result::{Ok, Err};
158157

@@ -172,7 +171,7 @@ struct RcBox<T> {
172171
pub struct Rc<T> {
173172
// FIXME #12808: strange names to try to avoid interfering with
174173
// field accesses of the contained type via Deref
175-
_ptr: *mut RcBox<T>,
174+
_ptr: NonZero<*mut RcBox<T>>,
176175
_nosend: marker::NoSend,
177176
_noshare: marker::NoSync
178177
}
@@ -196,11 +195,11 @@ impl<T> Rc<T> {
196195
// destructor never frees the allocation while the
197196
// strong destructor is running, even if the weak
198197
// pointer is stored inside the strong one.
199-
_ptr: transmute(box RcBox {
198+
_ptr: NonZero(transmute(box RcBox {
200199
value: value,
201200
strong: Cell::new(1),
202201
weak: Cell::new(1)
203-
}),
202+
})),
204203
_nosend: marker::NoSend,
205204
_noshare: marker::NoSync
206205
}
@@ -281,7 +280,8 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
281280
let val = ptr::read(&*rc); // copy the contained object
282281
// destruct the box and skip our Drop
283282
// we can ignore the refcounts because we know we're unique
284-
deallocate(rc._ptr as *mut u8, size_of::<RcBox<T>>(),
283+
let NonZero(ptr) = rc._ptr;
284+
deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
285285
min_align_of::<RcBox<T>>());
286286
forget(rc);
287287
Ok(val)
@@ -311,7 +311,10 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
311311
#[experimental]
312312
pub fn get_mut<'a, T>(rc: &'a mut Rc<T>) -> Option<&'a mut T> {
313313
if is_unique(rc) {
314-
let inner = unsafe { &mut *rc._ptr };
314+
let inner = unsafe {
315+
let NonZero(ptr) = rc._ptr;
316+
&mut *ptr
317+
};
315318
Some(&mut inner.value)
316319
} else {
317320
None
@@ -344,7 +347,10 @@ impl<T: Clone> Rc<T> {
344347
// reference count is guaranteed to be 1 at this point, and we required
345348
// the `Rc<T>` itself to be `mut`, so we're returning the only possible
346349
// reference to the inner value.
347-
let inner = unsafe { &mut *self._ptr };
350+
let inner = unsafe {
351+
let NonZero(ptr) = self._ptr;
352+
&mut *ptr
353+
};
348354
&mut inner.value
349355
}
350356
}
@@ -386,7 +392,8 @@ impl<T> Drop for Rc<T> {
386392
/// ```
387393
fn drop(&mut self) {
388394
unsafe {
389-
if !self._ptr.is_null() {
395+
let NonZero(ptr) = self._ptr;
396+
if !ptr.is_null() {
390397
self.dec_strong();
391398
if self.strong() == 0 {
392399
ptr::read(&**self); // destroy the contained object
@@ -396,7 +403,7 @@ impl<T> Drop for Rc<T> {
396403
self.dec_weak();
397404

398405
if self.weak() == 0 {
399-
deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
406+
deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
400407
min_align_of::<RcBox<T>>())
401408
}
402409
}
@@ -604,7 +611,7 @@ impl<T: fmt::Show> fmt::Show for Rc<T> {
604611
pub struct Weak<T> {
605612
// FIXME #12808: strange names to try to avoid interfering with
606613
// field accesses of the contained type via Deref
607-
_ptr: *mut RcBox<T>,
614+
_ptr: NonZero<*mut RcBox<T>>,
608615
_nosend: marker::NoSend,
609616
_noshare: marker::NoSync
610617
}
@@ -668,12 +675,13 @@ impl<T> Drop for Weak<T> {
668675
/// ```
669676
fn drop(&mut self) {
670677
unsafe {
671-
if !self._ptr.is_null() {
678+
let NonZero(ptr) = self._ptr;
679+
if !ptr.is_null() {
672680
self.dec_weak();
673681
// the weak count starts at 1, and will only go to
674682
// zero if all the strong pointers have disappeared.
675683
if self.weak() == 0 {
676-
deallocate(self._ptr as *mut u8, size_of::<RcBox<T>>(),
684+
deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
677685
min_align_of::<RcBox<T>>())
678686
}
679687
}
@@ -728,12 +736,18 @@ trait RcBoxPtr<T> {
728736

729737
impl<T> RcBoxPtr<T> for Rc<T> {
730738
#[inline(always)]
731-
fn inner(&self) -> &RcBox<T> { unsafe { &(*self._ptr) } }
739+
fn inner(&self) -> &RcBox<T> {
740+
let NonZero(ptr) = self._ptr;
741+
unsafe { &(*ptr) }
742+
}
732743
}
733744

734745
impl<T> RcBoxPtr<T> for Weak<T> {
735746
#[inline(always)]
736-
fn inner(&self) -> &RcBox<T> { unsafe { &(*self._ptr) } }
747+
fn inner(&self) -> &RcBox<T> {
748+
let NonZero(ptr) = self._ptr;
749+
unsafe { &(*ptr) }
750+
}
737751
}
738752

739753
#[cfg(test)]

0 commit comments

Comments
 (0)