Rollup merge of #42959 - SimonSapin:nonzero-checked, r=sfackler
Make the "main" constructors of NonZero/Shared/Unique return Option Per discussion in https://github.com/rust-lang/rust/issues/27730#issuecomment-303939441. This is a breaking change to unstable APIs. The old behavior is still available under the name `new_unchecked`. Note that only that one can be `const fn`, since `if` is currently not allowed in constant contexts. In the case of `NonZero` this requires adding a new `is_zero` method to the `Zeroable` trait. I mildly dislike this, but it’s not much worse than having a `Zeroable` trait in the first place. `Zeroable` and `NonZero` are both unstable, this can be reworked later.
This commit is contained in:
commit
b5b7266b78
21 changed files with 218 additions and 86 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 81134a4dff811403b3b2f349b0c59a819f0fe0c1
|
||||
Subproject commit f8fd6710399a1a557155cb5be4922fe6a6f694c0
|
|
@ -892,7 +892,7 @@ pub unsafe trait Alloc {
|
|||
{
|
||||
let k = Layout::new::<T>();
|
||||
if k.size() > 0 {
|
||||
unsafe { self.alloc(k).map(|p| Unique::new(p as *mut T)) }
|
||||
unsafe { self.alloc(k).map(|p| Unique::new_unchecked(p as *mut T)) }
|
||||
} else {
|
||||
Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one"))
|
||||
}
|
||||
|
@ -963,7 +963,7 @@ pub unsafe trait Alloc {
|
|||
unsafe {
|
||||
self.alloc(layout.clone())
|
||||
.map(|p| {
|
||||
Unique::new(p as *mut T)
|
||||
Unique::new_unchecked(p as *mut T)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1012,7 +1012,7 @@ pub unsafe trait Alloc {
|
|||
match (Layout::array::<T>(n_old), Layout::array::<T>(n_new), ptr.as_ptr()) {
|
||||
(Some(ref k_old), Some(ref k_new), ptr) if k_old.size() > 0 && k_new.size() > 0 => {
|
||||
self.realloc(ptr as *mut u8, k_old.clone(), k_new.clone())
|
||||
.map(|p|Unique::new(p as *mut T))
|
||||
.map(|p|Unique::new_unchecked(p as *mut T))
|
||||
}
|
||||
_ => {
|
||||
Err(AllocErr::invalid_input("invalid layout for realloc_array"))
|
||||
|
|
|
@ -280,7 +280,7 @@ impl<T> Arc<T> {
|
|||
weak: atomic::AtomicUsize::new(1),
|
||||
data: data,
|
||||
};
|
||||
Arc { ptr: unsafe { Shared::new(Box::into_raw(x)) } }
|
||||
Arc { ptr: Shared::from(Box::into_unique(x)) }
|
||||
}
|
||||
|
||||
/// Returns the contained value, if the `Arc` has exactly one strong reference.
|
||||
|
@ -382,7 +382,7 @@ impl<T> Arc<T> {
|
|||
// `data` field from the pointer.
|
||||
let ptr = (ptr as *const u8).offset(-offset_of!(ArcInner<T>, data));
|
||||
Arc {
|
||||
ptr: Shared::new(ptr as *mut u8 as *mut _),
|
||||
ptr: Shared::new_unchecked(ptr as *mut u8 as *mut _),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -842,7 +842,7 @@ impl<T> Weak<T> {
|
|||
pub fn new() -> Weak<T> {
|
||||
unsafe {
|
||||
Weak {
|
||||
ptr: Shared::new(Box::into_raw(box ArcInner {
|
||||
ptr: Shared::from(Box::into_unique(box ArcInner {
|
||||
strong: atomic::AtomicUsize::new(0),
|
||||
weak: atomic::AtomicUsize::new(1),
|
||||
data: uninitialized(),
|
||||
|
|
|
@ -297,6 +297,37 @@ impl<T: ?Sized> Box<T> {
|
|||
pub fn into_raw(b: Box<T>) -> *mut T {
|
||||
unsafe { mem::transmute(b) }
|
||||
}
|
||||
|
||||
/// Consumes the `Box`, returning the wrapped pointer as `Unique<T>`.
|
||||
///
|
||||
/// After calling this function, the caller is responsible for the
|
||||
/// memory previously managed by the `Box`. In particular, the
|
||||
/// caller should properly destroy `T` and release the memory. The
|
||||
/// proper way to do so is to convert the raw pointer back into a
|
||||
/// `Box` with the [`Box::from_raw`] function.
|
||||
///
|
||||
/// Note: this is an associated function, which means that you have
|
||||
/// to call it as `Box::into_unique(b)` instead of `b.into_unique()`. This
|
||||
/// is so that there is no conflict with a method on the inner type.
|
||||
///
|
||||
/// [`Box::from_raw`]: struct.Box.html#method.from_raw
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(unique)]
|
||||
///
|
||||
/// fn main() {
|
||||
/// let x = Box::new(5);
|
||||
/// let ptr = Box::into_unique(x);
|
||||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
|
||||
issue = "27730")]
|
||||
#[inline]
|
||||
pub fn into_unique(b: Box<T>) -> Unique<T> {
|
||||
unsafe { mem::transmute(b) }
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
|
@ -140,24 +140,22 @@ struct BoxedNode<K, V> {
|
|||
|
||||
impl<K, V> BoxedNode<K, V> {
|
||||
fn from_leaf(node: Box<LeafNode<K, V>>) -> Self {
|
||||
unsafe {
|
||||
BoxedNode { ptr: Unique::new(Box::into_raw(node)) }
|
||||
}
|
||||
BoxedNode { ptr: Box::into_unique(node) }
|
||||
}
|
||||
|
||||
fn from_internal(node: Box<InternalNode<K, V>>) -> Self {
|
||||
unsafe {
|
||||
BoxedNode { ptr: Unique::new(Box::into_raw(node) as *mut LeafNode<K, V>) }
|
||||
BoxedNode { ptr: Unique::new_unchecked(Box::into_raw(node) as *mut LeafNode<K, V>) }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn from_ptr(ptr: NonZero<*const LeafNode<K, V>>) -> Self {
|
||||
BoxedNode { ptr: Unique::new(ptr.get() as *mut LeafNode<K, V>) }
|
||||
BoxedNode { ptr: Unique::new_unchecked(ptr.get() as *mut LeafNode<K, V>) }
|
||||
}
|
||||
|
||||
fn as_ptr(&self) -> NonZero<*const LeafNode<K, V>> {
|
||||
unsafe {
|
||||
NonZero::new(self.ptr.as_ptr())
|
||||
NonZero::from(self.ptr.as_ref())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -384,21 +382,19 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
|
|||
>,
|
||||
Self
|
||||
> {
|
||||
if self.as_leaf().parent.is_null() {
|
||||
Err(self)
|
||||
} else {
|
||||
if let Some(non_zero) = NonZero::new(self.as_leaf().parent as *const LeafNode<K, V>) {
|
||||
Ok(Handle {
|
||||
node: NodeRef {
|
||||
height: self.height + 1,
|
||||
node: unsafe {
|
||||
NonZero::new(self.as_leaf().parent as *mut LeafNode<K, V>)
|
||||
},
|
||||
node: non_zero,
|
||||
root: self.root,
|
||||
_marker: PhantomData
|
||||
},
|
||||
idx: self.as_leaf().parent_idx as usize,
|
||||
_marker: PhantomData
|
||||
})
|
||||
} else {
|
||||
Err(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ impl<T> LinkedList<T> {
|
|||
unsafe {
|
||||
node.next = self.head;
|
||||
node.prev = None;
|
||||
let node = Some(Shared::new(Box::into_raw(node)));
|
||||
let node = Some(Shared::from(Box::into_unique(node)));
|
||||
|
||||
match self.head {
|
||||
None => self.tail = node,
|
||||
|
@ -192,7 +192,7 @@ impl<T> LinkedList<T> {
|
|||
unsafe {
|
||||
node.next = None;
|
||||
node.prev = self.tail;
|
||||
let node = Some(Shared::new(Box::into_raw(node)));
|
||||
let node = Some(Shared::from(Box::into_unique(node)));
|
||||
|
||||
match self.tail {
|
||||
None => self.head = node,
|
||||
|
@ -921,7 +921,7 @@ impl<'a, T> IterMut<'a, T> {
|
|||
Some(prev) => prev,
|
||||
};
|
||||
|
||||
let node = Some(Shared::new(Box::into_raw(box Node {
|
||||
let node = Some(Shared::from(Box::into_unique(box Node {
|
||||
next: Some(head),
|
||||
prev: Some(prev),
|
||||
element: element,
|
||||
|
|
|
@ -104,7 +104,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
|||
};
|
||||
|
||||
RawVec {
|
||||
ptr: Unique::new(ptr as *mut _),
|
||||
ptr: Unique::new_unchecked(ptr as *mut _),
|
||||
cap: cap,
|
||||
a: a,
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ impl<T, A: Alloc> RawVec<T, A> {
|
|||
/// If the ptr and capacity come from a RawVec created via `a`, then this is guaranteed.
|
||||
pub unsafe fn from_raw_parts_in(ptr: *mut T, cap: usize, a: A) -> Self {
|
||||
RawVec {
|
||||
ptr: Unique::new(ptr),
|
||||
ptr: Unique::new_unchecked(ptr),
|
||||
cap: cap,
|
||||
a: a,
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ impl<T> RawVec<T, Heap> {
|
|||
/// If the ptr and capacity come from a RawVec, then this is guaranteed.
|
||||
pub unsafe fn from_raw_parts(ptr: *mut T, cap: usize) -> Self {
|
||||
RawVec {
|
||||
ptr: Unique::new(ptr),
|
||||
ptr: Unique::new_unchecked(ptr),
|
||||
cap: cap,
|
||||
a: Heap,
|
||||
}
|
||||
|
|
|
@ -303,18 +303,16 @@ impl<T> Rc<T> {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new(value: T) -> Rc<T> {
|
||||
unsafe {
|
||||
Rc {
|
||||
// there is an implicit weak pointer owned by all the strong
|
||||
// pointers, which ensures that the weak destructor never frees
|
||||
// the allocation while the strong destructor is running, even
|
||||
// if the weak pointer is stored inside the strong one.
|
||||
ptr: Shared::new(Box::into_raw(box RcBox {
|
||||
strong: Cell::new(1),
|
||||
weak: Cell::new(1),
|
||||
value: value,
|
||||
})),
|
||||
}
|
||||
Rc {
|
||||
// there is an implicit weak pointer owned by all the strong
|
||||
// pointers, which ensures that the weak destructor never frees
|
||||
// the allocation while the strong destructor is running, even
|
||||
// if the weak pointer is stored inside the strong one.
|
||||
ptr: Shared::from(Box::into_unique(box RcBox {
|
||||
strong: Cell::new(1),
|
||||
weak: Cell::new(1),
|
||||
value: value,
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,7 +416,7 @@ impl<T> Rc<T> {
|
|||
|
||||
let ptr = (ptr as *const u8).offset(-offset_of!(RcBox<T>, value));
|
||||
Rc {
|
||||
ptr: Shared::new(ptr as *mut u8 as *mut _)
|
||||
ptr: Shared::new_unchecked(ptr as *mut u8 as *mut _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -443,7 +441,7 @@ impl Rc<str> {
|
|||
// Combine the allocation address and the string length into a fat pointer to `RcBox`.
|
||||
let rcbox_ptr: *mut RcBox<str> = mem::transmute([ptr as usize, value.len()]);
|
||||
assert!(aligned_len * size_of::<usize>() == size_of_val(&*rcbox_ptr));
|
||||
Rc { ptr: Shared::new(rcbox_ptr) }
|
||||
Rc { ptr: Shared::new_unchecked(rcbox_ptr) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -476,7 +474,7 @@ impl<T> Rc<[T]> {
|
|||
// Free the original allocation without freeing its (moved) contents.
|
||||
box_free(Box::into_raw(value));
|
||||
|
||||
Rc { ptr: Shared::new(ptr as *mut _) }
|
||||
Rc { ptr: Shared::new_unchecked(ptr as *mut _) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1016,7 +1014,7 @@ impl<T> Weak<T> {
|
|||
pub fn new() -> Weak<T> {
|
||||
unsafe {
|
||||
Weak {
|
||||
ptr: Shared::new(Box::into_raw(box RcBox {
|
||||
ptr: Shared::from(Box::into_unique(box RcBox {
|
||||
strong: Cell::new(0),
|
||||
weak: Cell::new(1),
|
||||
value: uninitialized(),
|
||||
|
|
|
@ -1126,7 +1126,7 @@ impl<T> Vec<T> {
|
|||
tail_start: end,
|
||||
tail_len: len - end,
|
||||
iter: range_slice.iter(),
|
||||
vec: Shared::new(self as *mut _),
|
||||
vec: Shared::from(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1727,7 +1727,7 @@ impl<T> IntoIterator for Vec<T> {
|
|||
let cap = self.buf.cap();
|
||||
mem::forget(self);
|
||||
IntoIter {
|
||||
buf: Shared::new(begin),
|
||||
buf: Shared::new_unchecked(begin),
|
||||
cap: cap,
|
||||
ptr: begin,
|
||||
end: end,
|
||||
|
|
|
@ -893,7 +893,7 @@ impl<T> VecDeque<T> {
|
|||
self.head = drain_tail;
|
||||
|
||||
Drain {
|
||||
deque: unsafe { Shared::new(self as *mut _) },
|
||||
deque: Shared::from(&mut *self),
|
||||
after_tail: drain_head,
|
||||
after_head: head,
|
||||
iter: Iter {
|
||||
|
|
|
@ -16,22 +16,48 @@
|
|||
use ops::CoerceUnsized;
|
||||
|
||||
/// Unsafe trait to indicate what types are usable with the NonZero struct
|
||||
pub unsafe trait Zeroable {}
|
||||
pub unsafe trait Zeroable {
|
||||
/// Whether this value is zero
|
||||
fn is_zero(&self) -> bool;
|
||||
}
|
||||
|
||||
unsafe impl<T:?Sized> Zeroable for *const T {}
|
||||
unsafe impl<T:?Sized> Zeroable for *mut T {}
|
||||
unsafe impl Zeroable for isize {}
|
||||
unsafe impl Zeroable for usize {}
|
||||
unsafe impl Zeroable for i8 {}
|
||||
unsafe impl Zeroable for u8 {}
|
||||
unsafe impl Zeroable for i16 {}
|
||||
unsafe impl Zeroable for u16 {}
|
||||
unsafe impl Zeroable for i32 {}
|
||||
unsafe impl Zeroable for u32 {}
|
||||
unsafe impl Zeroable for i64 {}
|
||||
unsafe impl Zeroable for u64 {}
|
||||
unsafe impl Zeroable for i128 {}
|
||||
unsafe impl Zeroable for u128 {}
|
||||
macro_rules! impl_zeroable_for_pointer_types {
|
||||
( $( $Ptr: ty )+ ) => {
|
||||
$(
|
||||
/// For fat pointers to be considered "zero", only the "data" part needs to be null.
|
||||
unsafe impl<T: ?Sized> Zeroable for $Ptr {
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
// Cast because `is_null` is only available on thin pointers
|
||||
(*self as *mut u8).is_null()
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_zeroable_for_integer_types {
|
||||
( $( $Int: ty )+ ) => {
|
||||
$(
|
||||
unsafe impl Zeroable for $Int {
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
*self == 0
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
impl_zeroable_for_pointer_types! {
|
||||
*const T
|
||||
*mut T
|
||||
}
|
||||
|
||||
impl_zeroable_for_integer_types! {
|
||||
usize u8 u16 u32 u64 u128
|
||||
isize i8 i16 i32 i64 i128
|
||||
}
|
||||
|
||||
/// A wrapper type for raw pointers and integers that will never be
|
||||
/// NULL or 0 that might allow certain optimizations.
|
||||
|
@ -43,10 +69,20 @@ impl<T: Zeroable> NonZero<T> {
|
|||
/// Creates an instance of NonZero with the provided value.
|
||||
/// You must indeed ensure that the value is actually "non-zero".
|
||||
#[inline]
|
||||
pub const unsafe fn new(inner: T) -> NonZero<T> {
|
||||
pub const unsafe fn new_unchecked(inner: T) -> Self {
|
||||
NonZero(inner)
|
||||
}
|
||||
|
||||
/// Creates an instance of NonZero with the provided value.
|
||||
#[inline]
|
||||
pub fn new(inner: T) -> Option<Self> {
|
||||
if inner.is_zero() {
|
||||
None
|
||||
} else {
|
||||
Some(NonZero(inner))
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the inner value.
|
||||
pub fn get(self) -> T {
|
||||
self.0
|
||||
|
@ -54,3 +90,22 @@ impl<T: Zeroable> NonZero<T> {
|
|||
}
|
||||
|
||||
impl<T: Zeroable+CoerceUnsized<U>, U: Zeroable> CoerceUnsized<NonZero<U>> for NonZero<T> {}
|
||||
|
||||
impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*mut T> {
|
||||
fn from(reference: &'a mut T) -> Self {
|
||||
NonZero(reference)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*const T> {
|
||||
fn from(reference: &'a mut T) -> Self {
|
||||
let ptr: *mut T = reference;
|
||||
NonZero(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> From<&'a T> for NonZero<*const T> {
|
||||
fn from(reference: &'a T) -> Self {
|
||||
NonZero(reference)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use convert::From;
|
||||
use intrinsics;
|
||||
use ops::CoerceUnsized;
|
||||
use fmt;
|
||||
|
@ -1098,7 +1099,7 @@ impl<T: Sized> Unique<T> {
|
|||
pub fn empty() -> Self {
|
||||
unsafe {
|
||||
let ptr = mem::align_of::<T>() as *mut T;
|
||||
Unique::new(ptr)
|
||||
Unique::new_unchecked(ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1110,8 +1111,13 @@ impl<T: ?Sized> Unique<T> {
|
|||
/// # Safety
|
||||
///
|
||||
/// `ptr` must be non-null.
|
||||
pub const unsafe fn new(ptr: *mut T) -> Unique<T> {
|
||||
Unique { pointer: NonZero::new(ptr), _marker: PhantomData }
|
||||
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
|
||||
Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Creates a new `Unique` if `ptr` is non-null.
|
||||
pub fn new(ptr: *mut T) -> Option<Self> {
|
||||
NonZero::new(ptr as *const T).map(|nz| Unique { pointer: nz, _marker: PhantomData })
|
||||
}
|
||||
|
||||
/// Acquires the underlying `*mut` pointer.
|
||||
|
@ -1138,14 +1144,14 @@ impl<T: ?Sized> Unique<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "shared", issue = "27730")]
|
||||
#[unstable(feature = "unique", issue = "27730")]
|
||||
impl<T: ?Sized> Clone for Unique<T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "shared", issue = "27730")]
|
||||
#[unstable(feature = "unique", issue = "27730")]
|
||||
impl<T: ?Sized> Copy for Unique<T> { }
|
||||
|
||||
#[unstable(feature = "unique", issue = "27730")]
|
||||
|
@ -1158,6 +1164,20 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "unique", issue = "27730")]
|
||||
impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
|
||||
fn from(reference: &'a mut T) -> Self {
|
||||
Unique { pointer: NonZero::from(reference), _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "unique", issue = "27730")]
|
||||
impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
|
||||
fn from(reference: &'a T) -> Self {
|
||||
Unique { pointer: NonZero::from(reference), _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around a raw `*mut T` that indicates that the possessor
|
||||
/// of this wrapper has shared ownership of the referent. Useful for
|
||||
/// building abstractions like `Rc<T>`, `Arc<T>`, or doubly-linked lists, which
|
||||
|
@ -1212,7 +1232,7 @@ impl<T: Sized> Shared<T> {
|
|||
pub fn empty() -> Self {
|
||||
unsafe {
|
||||
let ptr = mem::align_of::<T>() as *mut T;
|
||||
Shared::new(ptr)
|
||||
Shared::new_unchecked(ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1224,8 +1244,13 @@ impl<T: ?Sized> Shared<T> {
|
|||
/// # Safety
|
||||
///
|
||||
/// `ptr` must be non-null.
|
||||
pub unsafe fn new(ptr: *mut T) -> Self {
|
||||
Shared { pointer: NonZero::new(ptr), _marker: PhantomData }
|
||||
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
|
||||
Shared { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Creates a new `Shared` if `ptr` is non-null.
|
||||
pub fn new(ptr: *mut T) -> Option<Self> {
|
||||
NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz, _marker: PhantomData })
|
||||
}
|
||||
|
||||
/// Acquires the underlying `*mut` pointer.
|
||||
|
@ -1278,3 +1303,24 @@ impl<T: ?Sized> fmt::Pointer for Shared<T> {
|
|||
fmt::Pointer::fmt(&self.as_ptr(), f)
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "shared", issue = "27730")]
|
||||
impl<T: ?Sized> From<Unique<T>> for Shared<T> {
|
||||
fn from(unique: Unique<T>) -> Self {
|
||||
Shared { pointer: unique.pointer, _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "shared", issue = "27730")]
|
||||
impl<'a, T: ?Sized> From<&'a mut T> for Shared<T> {
|
||||
fn from(reference: &'a mut T) -> Self {
|
||||
Shared { pointer: NonZero::from(reference), _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "shared", issue = "27730")]
|
||||
impl<'a, T: ?Sized> From<&'a T> for Shared<T> {
|
||||
fn from(reference: &'a T) -> Self {
|
||||
Shared { pointer: NonZero::from(reference), _marker: PhantomData }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::mem::size_of;
|
|||
#[test]
|
||||
fn test_create_nonzero_instance() {
|
||||
let _a = unsafe {
|
||||
NonZero::new(21)
|
||||
NonZero::new_unchecked(21)
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -28,14 +28,14 @@ fn test_size_nonzero_in_option() {
|
|||
#[test]
|
||||
fn test_match_on_nonzero_option() {
|
||||
let a = Some(unsafe {
|
||||
NonZero::new(42)
|
||||
NonZero::new_unchecked(42)
|
||||
});
|
||||
match a {
|
||||
Some(val) => assert_eq!(val.get(), 42),
|
||||
None => panic!("unexpected None while matching on Some(NonZero(_))")
|
||||
}
|
||||
|
||||
match unsafe { Some(NonZero::new(43)) } {
|
||||
match unsafe { Some(NonZero::new_unchecked(43)) } {
|
||||
Some(val) => assert_eq!(val.get(), 43),
|
||||
None => panic!("unexpected None while matching on Some(NonZero(_))")
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ fn test_set_memory() {
|
|||
#[test]
|
||||
fn test_unsized_unique() {
|
||||
let xs: &[i32] = &[1, 2, 3];
|
||||
let ptr = unsafe { Unique::new(xs as *const [i32] as *mut [i32]) };
|
||||
let ptr = unsafe { Unique::new_unchecked(xs as *const [i32] as *mut [i32]) };
|
||||
let ys = unsafe { ptr.as_ref() };
|
||||
let zs: &[i32] = &[1, 2, 3];
|
||||
assert!(ys == zs);
|
||||
|
|
|
@ -47,7 +47,7 @@ impl<'tcx> From<Ty<'tcx>> for Kind<'tcx> {
|
|||
let ptr = ty as *const _ as usize;
|
||||
Kind {
|
||||
ptr: unsafe {
|
||||
NonZero::new(ptr | TYPE_TAG)
|
||||
NonZero::new_unchecked(ptr | TYPE_TAG)
|
||||
},
|
||||
marker: PhantomData
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ impl<'tcx> From<ty::Region<'tcx>> for Kind<'tcx> {
|
|||
let ptr = r as *const _ as usize;
|
||||
Kind {
|
||||
ptr: unsafe {
|
||||
NonZero::new(ptr | REGION_TAG)
|
||||
NonZero::new_unchecked(ptr | REGION_TAG)
|
||||
},
|
||||
marker: PhantomData
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ impl<A: Array> ArrayVec<A> {
|
|||
tail_start: end,
|
||||
tail_len: len - end,
|
||||
iter: range_slice.iter(),
|
||||
array_vec: Shared::new(self as *mut _),
|
||||
array_vec: Shared::from(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ pub struct NodeIndex {
|
|||
impl NodeIndex {
|
||||
pub fn new(value: usize) -> NodeIndex {
|
||||
assert!(value < (u32::MAX as usize));
|
||||
unsafe { NodeIndex { index: NonZero::new((value as u32) + 1) } }
|
||||
NodeIndex { index: NonZero::new((value as u32) + 1).unwrap() }
|
||||
}
|
||||
|
||||
pub fn get(self) -> usize {
|
||||
|
|
|
@ -42,7 +42,7 @@ pub(crate) mod indexes {
|
|||
|
||||
impl Idx for $Index {
|
||||
fn new(idx: usize) -> Self {
|
||||
unsafe { $Index(NonZero::new(idx + 1)) }
|
||||
$Index(NonZero::new(idx + 1).unwrap())
|
||||
}
|
||||
fn index(self) -> usize {
|
||||
self.0.get() - 1
|
||||
|
|
|
@ -44,7 +44,7 @@ impl TaggedHashUintPtr {
|
|||
#[inline]
|
||||
unsafe fn new(ptr: *mut HashUint) -> Self {
|
||||
debug_assert!(ptr as usize & 1 == 0 || ptr as usize == EMPTY as usize);
|
||||
TaggedHashUintPtr(Unique::new(ptr))
|
||||
TaggedHashUintPtr(Unique::new_unchecked(ptr))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -56,7 +56,7 @@ impl TaggedHashUintPtr {
|
|||
} else {
|
||||
usize_ptr &= !1;
|
||||
}
|
||||
self.0 = Unique::new(usize_ptr as *mut HashUint)
|
||||
self.0 = Unique::new_unchecked(usize_ptr as *mut HashUint)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -877,7 +877,7 @@ impl<K, V> RawTable<K, V> {
|
|||
elems_left: elems_left,
|
||||
marker: marker::PhantomData,
|
||||
},
|
||||
table: unsafe { Shared::new(self) },
|
||||
table: Shared::from(self),
|
||||
marker: marker::PhantomData,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::ptr::Unique;
|
|||
|
||||
fn main() {
|
||||
let mut a = [0u8; 5];
|
||||
let b: Option<Unique<[u8]>> = unsafe { Some(Unique::new(&mut a)) };
|
||||
let b: Option<Unique<[u8]>> = Some(Unique::from(&mut a));
|
||||
match b {
|
||||
Some(_) => println!("Got `Some`"),
|
||||
None => panic!("Unexpected `None`"),
|
||||
|
|
|
@ -42,7 +42,7 @@ impl Default for EmbeddedDiscr {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct IndirectNonZero<T: Zeroable> {
|
||||
pub struct IndirectNonZero<T: Zeroable + One> {
|
||||
pre: u8,
|
||||
nested: NestedNonZero<T>,
|
||||
post: u16,
|
||||
|
@ -54,14 +54,20 @@ pub struct NestedNonZero<T: Zeroable> {
|
|||
post: u16,
|
||||
}
|
||||
|
||||
impl<T: Zeroable+Default> Default for NestedNonZero<T> {
|
||||
impl<T: Zeroable+One> Default for NestedNonZero<T> {
|
||||
fn default() -> Self {
|
||||
unsafe {
|
||||
NestedNonZero { pre: 0, val: NonZero::new(Default::default()), post: 0 }
|
||||
}
|
||||
NestedNonZero { pre: 0, val: NonZero::new(T::one()).unwrap(), post: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
pub trait One {
|
||||
fn one() -> Self;
|
||||
}
|
||||
|
||||
impl One for u32 {
|
||||
fn one() -> Self { 1 }
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let _x: MyOption<NonZero<u32>> = Default::default();
|
||||
let _y: EmbeddedDiscr = Default::default();
|
||||
|
|
Loading…
Add table
Reference in a new issue