1
Fork 0

libcore: Make it unsafe to create NonZero and impl Deref.

This commit is contained in:
Luqman Aden 2014-12-04 14:58:21 -05:00
parent 4af50548b9
commit 466135bfef
4 changed files with 55 additions and 59 deletions

View file

@ -164,7 +164,7 @@ impl<T> Arc<T> {
weak: atomic::AtomicUint::new(1),
data: data,
};
Arc { _ptr: NonZero(unsafe { mem::transmute(x) }) }
Arc { _ptr: unsafe { NonZero::new(mem::transmute(x)) } }
}
/// Downgrades the `Arc<T>` to a `Weak<T>` reference.
@ -193,8 +193,7 @@ impl<T> Arc<T> {
// pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync`
// because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer
// to these contents.
let NonZero(ptr) = self._ptr;
unsafe { &*ptr }
unsafe { &**self._ptr }
}
}
@ -281,8 +280,7 @@ impl<T: Send + Sync + Clone> Arc<T> {
// pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
// this point, and we required the Arc itself to be `mut`, so we're returning the only
// possible reference to the inner data.
let NonZero(ptr) = self._ptr;
let inner = unsafe { &mut *ptr };
let inner = unsafe { &mut **self._ptr };
&mut inner.data
}
}
@ -317,7 +315,7 @@ impl<T: Sync + Send> Drop for Arc<T> {
fn drop(&mut self) {
// This structure has #[unsafe_no_drop_flag], so this drop glue may run more than once (but
// it is guaranteed to be zeroed after the first if it's run more than once)
let NonZero(ptr) = self._ptr;
let ptr = *self._ptr;
if ptr.is_null() { return }
// Because `fetch_sub` is already atomic, we do not need to synchronize with other threads
@ -388,8 +386,7 @@ impl<T: Sync + Send> Weak<T> {
#[inline]
fn inner(&self) -> &ArcInner<T> {
// See comments above for why this is "safe"
let NonZero(ptr) = self._ptr;
unsafe { &*ptr }
unsafe { &**self._ptr }
}
}
@ -445,7 +442,7 @@ impl<T: Sync + Send> Drop for Weak<T> {
/// } // implicit drop
/// ```
fn drop(&mut self) {
let NonZero(ptr) = self._ptr;
let ptr = *self._ptr;
// see comments above for why this check is here
if ptr.is_null() { return }