Auto merge of #46952 - SimonSapin:nonnull, r=alexcrichton

Rename std::ptr::Shared to NonNull and stabilize it

This implements the changes proposed at https://github.com/rust-lang/rust/issues/27730#issuecomment-352800629:

> * Rename `Shared<T>` to `NonNull<T>` and stabilize it. (Being in the `ptr` module is enough to say that it’s a pointer. I’m not very attached to this specific name though.)
> * Rename `Box<T>` methods ~~`from_unique`~~/`into_unique` to ~~`from_nonnull`~~/`into_nonnull` (or whatever names are deemed appropriate), replace `Unique<T>` with `NonNull<T>` in their signatures, and stabilize them.
> *  Replace `Unique<T>` with `NonNull<T>` in the signatures of methods of the `Alloc` trait.
> * Mark `Unique` “permanently-unstable” by replacing remaining occurrences of `#[unstable(feature = "unique", issue = "27730")]` with:
>
>   ```rust
>   #[unstable(feature = "ptr_internals", issue = "0", reason = "\
>       use NonNull instead and consider PhantomData<T> (if you also use #[may_dangle]), \
>       Send, and/or Sync")]
>   ```
>
>   (Maybe the `reason` string is only useful on the struct definition.) Ideally it would be made private to some crate instead, but it needs to be used in both liballoc and libstd.
> * (Leave `NonZero` and `Zeroable` unstable for now, and subject to future bikeshedding.)
This commit is contained in:
bors 2018-01-20 12:28:13 +00:00
commit bdda8d6115
22 changed files with 183 additions and 198 deletions

@ -1 +1 @@
Subproject commit 2f7b05fd5939aa49d52c4ab309b9a47776ba7bd8 Subproject commit fec3182d0b0a3cf8122e192b3270064a5b19be5b

View File

@ -19,7 +19,7 @@ use core::cmp;
use core::fmt; use core::fmt;
use core::mem; use core::mem;
use core::usize; use core::usize;
use core::ptr::{self, Unique}; use core::ptr::{self, NonNull};
/// Represents the combination of a starting address and /// Represents the combination of a starting address and
/// a total capacity of the returned block. /// a total capacity of the returned block.
@ -895,12 +895,12 @@ pub unsafe trait Alloc {
/// Clients wishing to abort computation in response to an /// Clients wishing to abort computation in response to an
/// allocation error are encouraged to call the allocator's `oom` /// allocation error are encouraged to call the allocator's `oom`
/// method, rather than directly invoking `panic!` or similar. /// method, rather than directly invoking `panic!` or similar.
fn alloc_one<T>(&mut self) -> Result<Unique<T>, AllocErr> fn alloc_one<T>(&mut self) -> Result<NonNull<T>, AllocErr>
where Self: Sized where Self: Sized
{ {
let k = Layout::new::<T>(); let k = Layout::new::<T>();
if k.size() > 0 { if k.size() > 0 {
unsafe { self.alloc(k).map(|p| Unique::new_unchecked(p as *mut T)) } unsafe { self.alloc(k).map(|p| NonNull::new_unchecked(p as *mut T)) }
} else { } else {
Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one")) Err(AllocErr::invalid_input("zero-sized type invalid for alloc_one"))
} }
@ -923,7 +923,7 @@ pub unsafe trait Alloc {
/// * `ptr` must denote a block of memory currently allocated via this allocator /// * `ptr` must denote a block of memory currently allocated via this allocator
/// ///
/// * the layout of `T` must *fit* that block of memory. /// * the layout of `T` must *fit* that block of memory.
unsafe fn dealloc_one<T>(&mut self, ptr: Unique<T>) unsafe fn dealloc_one<T>(&mut self, ptr: NonNull<T>)
where Self: Sized where Self: Sized
{ {
let raw_ptr = ptr.as_ptr() as *mut u8; let raw_ptr = ptr.as_ptr() as *mut u8;
@ -963,7 +963,7 @@ pub unsafe trait Alloc {
/// Clients wishing to abort computation in response to an /// Clients wishing to abort computation in response to an
/// allocation error are encouraged to call the allocator's `oom` /// allocation error are encouraged to call the allocator's `oom`
/// method, rather than directly invoking `panic!` or similar. /// method, rather than directly invoking `panic!` or similar.
fn alloc_array<T>(&mut self, n: usize) -> Result<Unique<T>, AllocErr> fn alloc_array<T>(&mut self, n: usize) -> Result<NonNull<T>, AllocErr>
where Self: Sized where Self: Sized
{ {
match Layout::array::<T>(n) { match Layout::array::<T>(n) {
@ -971,7 +971,7 @@ pub unsafe trait Alloc {
unsafe { unsafe {
self.alloc(layout.clone()) self.alloc(layout.clone())
.map(|p| { .map(|p| {
Unique::new_unchecked(p as *mut T) NonNull::new_unchecked(p as *mut T)
}) })
} }
} }
@ -1012,15 +1012,15 @@ pub unsafe trait Alloc {
/// reallocation error are encouraged to call the allocator's `oom` /// reallocation error are encouraged to call the allocator's `oom`
/// method, rather than directly invoking `panic!` or similar. /// method, rather than directly invoking `panic!` or similar.
unsafe fn realloc_array<T>(&mut self, unsafe fn realloc_array<T>(&mut self,
ptr: Unique<T>, ptr: NonNull<T>,
n_old: usize, n_old: usize,
n_new: usize) -> Result<Unique<T>, AllocErr> n_new: usize) -> Result<NonNull<T>, AllocErr>
where Self: Sized where Self: Sized
{ {
match (Layout::array::<T>(n_old), Layout::array::<T>(n_new), ptr.as_ptr()) { 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 => { (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()) self.realloc(ptr as *mut u8, k_old.clone(), k_new.clone())
.map(|p|Unique::new_unchecked(p as *mut T)) .map(|p| NonNull::new_unchecked(p as *mut T))
} }
_ => { _ => {
Err(AllocErr::invalid_input("invalid layout for realloc_array")) Err(AllocErr::invalid_input("invalid layout for realloc_array"))
@ -1048,7 +1048,7 @@ pub unsafe trait Alloc {
/// constraints. /// constraints.
/// ///
/// Always returns `Err` on arithmetic overflow. /// Always returns `Err` on arithmetic overflow.
unsafe fn dealloc_array<T>(&mut self, ptr: Unique<T>, n: usize) -> Result<(), AllocErr> unsafe fn dealloc_array<T>(&mut self, ptr: NonNull<T>, n: usize) -> Result<(), AllocErr>
where Self: Sized where Self: Sized
{ {
let raw_ptr = ptr.as_ptr() as *mut u8; let raw_ptr = ptr.as_ptr() as *mut u8;

View File

@ -25,7 +25,7 @@ use core::intrinsics::abort;
use core::mem::{self, align_of_val, size_of_val, uninitialized}; use core::mem::{self, align_of_val, size_of_val, uninitialized};
use core::ops::Deref; use core::ops::Deref;
use core::ops::CoerceUnsized; use core::ops::CoerceUnsized;
use core::ptr::{self, Shared}; use core::ptr::{self, NonNull};
use core::marker::{Unsize, PhantomData}; use core::marker::{Unsize, PhantomData};
use core::hash::{Hash, Hasher}; use core::hash::{Hash, Hasher};
use core::{isize, usize}; use core::{isize, usize};
@ -197,7 +197,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
/// [rc_examples]: ../../std/rc/index.html#examples /// [rc_examples]: ../../std/rc/index.html#examples
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Arc<T: ?Sized> { pub struct Arc<T: ?Sized> {
ptr: Shared<ArcInner<T>>, ptr: NonNull<ArcInner<T>>,
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
@ -234,7 +234,7 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
/// [`None`]: ../../std/option/enum.Option.html#variant.None /// [`None`]: ../../std/option/enum.Option.html#variant.None
#[stable(feature = "arc_weak", since = "1.4.0")] #[stable(feature = "arc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> { pub struct Weak<T: ?Sized> {
ptr: Shared<ArcInner<T>>, ptr: NonNull<ArcInner<T>>,
} }
#[stable(feature = "arc_weak", since = "1.4.0")] #[stable(feature = "arc_weak", since = "1.4.0")]
@ -286,7 +286,7 @@ impl<T> Arc<T> {
weak: atomic::AtomicUsize::new(1), weak: atomic::AtomicUsize::new(1),
data, data,
}; };
Arc { ptr: Shared::from(Box::into_unique(x)), phantom: PhantomData } Arc { ptr: Box::into_raw_non_null(x), phantom: PhantomData }
} }
/// Returns the contained value, if the `Arc` has exactly one strong reference. /// Returns the contained value, if the `Arc` has exactly one strong reference.
@ -397,7 +397,7 @@ impl<T: ?Sized> Arc<T> {
let arc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); let arc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
Arc { Arc {
ptr: Shared::new_unchecked(arc_ptr), ptr: NonNull::new_unchecked(arc_ptr),
phantom: PhantomData, phantom: PhantomData,
} }
} }
@ -582,7 +582,7 @@ impl<T: ?Sized> Arc<T> {
// Free the allocation without dropping its contents // Free the allocation without dropping its contents
box_free(bptr); box_free(bptr);
Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
} }
} }
} }
@ -609,7 +609,7 @@ impl<T> Arc<[T]> {
&mut (*ptr).data as *mut [T] as *mut T, &mut (*ptr).data as *mut [T] as *mut T,
v.len()); v.len());
Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
} }
} }
@ -669,7 +669,7 @@ impl<T: Clone> ArcFromSlice<T> for Arc<[T]> {
// All clear. Forget the guard so it doesn't free the new ArcInner. // All clear. Forget the guard so it doesn't free the new ArcInner.
mem::forget(guard); mem::forget(guard);
Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
} }
} }
} }
@ -991,11 +991,11 @@ impl<T> Weak<T> {
pub fn new() -> Weak<T> { pub fn new() -> Weak<T> {
unsafe { unsafe {
Weak { Weak {
ptr: Shared::from(Box::into_unique(box ArcInner { ptr: Box::into_raw_non_null(box ArcInner {
strong: atomic::AtomicUsize::new(0), strong: atomic::AtomicUsize::new(0),
weak: atomic::AtomicUsize::new(1), weak: atomic::AtomicUsize::new(1),
data: uninitialized(), data: uninitialized(),
})), }),
} }
} }
} }

View File

@ -68,7 +68,7 @@ use core::marker::{self, Unsize};
use core::mem; use core::mem;
use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState}; use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState};
use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer}; use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer};
use core::ptr::{self, Unique}; use core::ptr::{self, NonNull, Unique};
use core::convert::From; use core::convert::From;
use str::from_boxed_utf8_unchecked; use str::from_boxed_utf8_unchecked;
@ -269,38 +269,7 @@ impl<T: ?Sized> Box<T> {
#[stable(feature = "box_raw", since = "1.4.0")] #[stable(feature = "box_raw", since = "1.4.0")]
#[inline] #[inline]
pub unsafe fn from_raw(raw: *mut T) -> Self { pub unsafe fn from_raw(raw: *mut T) -> Self {
Box::from_unique(Unique::new_unchecked(raw)) Box(Unique::new_unchecked(raw))
}
/// Constructs a `Box` from a `Unique<T>` pointer.
///
/// After calling this function, the memory is owned by a `Box` and `T` can
/// then be destroyed and released upon drop.
///
/// # Safety
///
/// A `Unique<T>` can be safely created via [`Unique::new`] and thus doesn't
/// necessarily own the data pointed to nor is the data guaranteed to live
/// as long as the pointer.
///
/// [`Unique::new`]: ../../core/ptr/struct.Unique.html#method.new
///
/// # Examples
///
/// ```
/// #![feature(unique)]
///
/// fn main() {
/// let x = Box::new(5);
/// let ptr = Box::into_unique(x);
/// let x = unsafe { Box::from_unique(ptr) };
/// }
/// ```
#[unstable(feature = "unique", reason = "needs an RFC to flesh out design",
issue = "27730")]
#[inline]
pub unsafe fn from_unique(u: Unique<T>) -> Self {
Box(u)
} }
/// Consumes the `Box`, returning the wrapped raw pointer. /// Consumes the `Box`, returning the wrapped raw pointer.
@ -326,40 +295,42 @@ impl<T: ?Sized> Box<T> {
#[stable(feature = "box_raw", since = "1.4.0")] #[stable(feature = "box_raw", since = "1.4.0")]
#[inline] #[inline]
pub fn into_raw(b: Box<T>) -> *mut T { pub fn into_raw(b: Box<T>) -> *mut T {
Box::into_unique(b).as_ptr() Box::into_raw_non_null(b).as_ptr()
} }
/// Consumes the `Box`, returning the wrapped pointer as `Unique<T>`. /// Consumes the `Box`, returning the wrapped pointer as `NonNull<T>`.
/// ///
/// After calling this function, the caller is responsible for the /// After calling this function, the caller is responsible for the
/// memory previously managed by the `Box`. In particular, the /// memory previously managed by the `Box`. In particular, the
/// caller should properly destroy `T` and release the memory. The /// caller should properly destroy `T` and release the memory. The
/// proper way to do so is to either convert the `Unique<T>` pointer: /// proper way to do so is to convert the `NonNull<T>` pointer
/// /// into a raw pointer and back into a `Box` with the [`Box::from_raw`]
/// - Into a `Box` with the [`Box::from_unique`] function. /// function.
///
/// - Into a raw pointer and back into a `Box` with the [`Box::from_raw`]
/// function.
/// ///
/// Note: this is an associated function, which means that you have /// 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 /// to call it as `Box::into_raw_non_null(b)`
/// instead of `b.into_raw_non_null()`. This
/// is so that there is no conflict with a method on the inner type. /// is so that there is no conflict with a method on the inner type.
/// ///
/// [`Box::from_unique`]: struct.Box.html#method.from_unique
/// [`Box::from_raw`]: struct.Box.html#method.from_raw /// [`Box::from_raw`]: struct.Box.html#method.from_raw
/// ///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(unique)] /// #![feature(box_into_raw_non_null)]
/// ///
/// fn main() { /// fn main() {
/// let x = Box::new(5); /// let x = Box::new(5);
/// let ptr = Box::into_unique(x); /// let ptr = Box::into_raw_non_null(x);
/// } /// }
/// ``` /// ```
#[unstable(feature = "unique", reason = "needs an RFC to flesh out design", #[unstable(feature = "box_into_raw_non_null", issue = "47336")]
issue = "27730")] #[inline]
pub fn into_raw_non_null(b: Box<T>) -> NonNull<T> {
Box::into_unique(b).into()
}
#[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")]
#[inline] #[inline]
pub fn into_unique(b: Box<T>) -> Unique<T> { pub fn into_unique(b: Box<T>) -> Unique<T> {
let unique = b.0; let unique = b.0;

View File

@ -232,7 +232,7 @@ unsafe impl Alloc for Heap {
/// ///
/// This preserves the non-null invariant for types like `Box<T>`. The address /// This preserves the non-null invariant for types like `Box<T>`. The address
/// may overlap with non-zero-size memory allocations. /// may overlap with non-zero-size memory allocations.
#[rustc_deprecated(since = "1.19", reason = "Use Unique/Shared::empty() instead")] #[rustc_deprecated(since = "1.19", reason = "Use Unique/NonNull::empty() instead")]
#[unstable(feature = "heap_api", issue = "27700")] #[unstable(feature = "heap_api", issue = "27700")]
pub const EMPTY: *mut () = 1 as *mut (); pub const EMPTY: *mut () = 1 as *mut ();

View File

@ -84,6 +84,7 @@
#![cfg_attr(test, feature(rand, test))] #![cfg_attr(test, feature(rand, test))]
#![feature(allow_internal_unstable)] #![feature(allow_internal_unstable)]
#![feature(ascii_ctype)] #![feature(ascii_ctype)]
#![feature(box_into_raw_non_null)]
#![feature(box_patterns)] #![feature(box_patterns)]
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(cfg_target_has_atomic)] #![feature(cfg_target_has_atomic)]
@ -109,8 +110,8 @@
#![feature(pattern)] #![feature(pattern)]
#![feature(placement_in_syntax)] #![feature(placement_in_syntax)]
#![feature(placement_new_protocol)] #![feature(placement_new_protocol)]
#![feature(ptr_internals)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#![feature(shared)]
#![feature(slice_get_slice)] #![feature(slice_get_slice)]
#![feature(slice_patterns)] #![feature(slice_patterns)]
#![feature(slice_rsplit)] #![feature(slice_rsplit)]
@ -120,7 +121,6 @@
#![feature(trusted_len)] #![feature(trusted_len)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(unicode)] #![feature(unicode)]
#![feature(unique)]
#![feature(unsize)] #![feature(unsize)]
#![feature(allocator_internals)] #![feature(allocator_internals)]
#![feature(on_unimplemented)] #![feature(on_unimplemented)]

View File

@ -29,7 +29,7 @@ use core::iter::{FromIterator, FusedIterator};
use core::marker::PhantomData; use core::marker::PhantomData;
use core::mem; use core::mem;
use core::ops::{BoxPlace, InPlace, Place, Placer}; use core::ops::{BoxPlace, InPlace, Place, Placer};
use core::ptr::{self, Shared}; use core::ptr::{self, NonNull};
use boxed::{Box, IntermediateBox}; use boxed::{Box, IntermediateBox};
use super::SpecExtend; use super::SpecExtend;
@ -44,15 +44,15 @@ use super::SpecExtend;
/// more memory efficient and make better use of CPU cache. /// more memory efficient and make better use of CPU cache.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct LinkedList<T> { pub struct LinkedList<T> {
head: Option<Shared<Node<T>>>, head: Option<NonNull<Node<T>>>,
tail: Option<Shared<Node<T>>>, tail: Option<NonNull<Node<T>>>,
len: usize, len: usize,
marker: PhantomData<Box<Node<T>>>, marker: PhantomData<Box<Node<T>>>,
} }
struct Node<T> { struct Node<T> {
next: Option<Shared<Node<T>>>, next: Option<NonNull<Node<T>>>,
prev: Option<Shared<Node<T>>>, prev: Option<NonNull<Node<T>>>,
element: T, element: T,
} }
@ -65,8 +65,8 @@ struct Node<T> {
/// [`LinkedList`]: struct.LinkedList.html /// [`LinkedList`]: struct.LinkedList.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Iter<'a, T: 'a> { pub struct Iter<'a, T: 'a> {
head: Option<Shared<Node<T>>>, head: Option<NonNull<Node<T>>>,
tail: Option<Shared<Node<T>>>, tail: Option<NonNull<Node<T>>>,
len: usize, len: usize,
marker: PhantomData<&'a Node<T>>, marker: PhantomData<&'a Node<T>>,
} }
@ -98,8 +98,8 @@ impl<'a, T> Clone for Iter<'a, T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct IterMut<'a, T: 'a> { pub struct IterMut<'a, T: 'a> {
list: &'a mut LinkedList<T>, list: &'a mut LinkedList<T>,
head: Option<Shared<Node<T>>>, head: Option<NonNull<Node<T>>>,
tail: Option<Shared<Node<T>>>, tail: Option<NonNull<Node<T>>>,
len: usize, len: usize,
} }
@ -157,7 +157,7 @@ impl<T> LinkedList<T> {
unsafe { unsafe {
node.next = self.head; node.next = self.head;
node.prev = None; node.prev = None;
let node = Some(Shared::from(Box::into_unique(node))); let node = Some(Box::into_raw_non_null(node));
match self.head { match self.head {
None => self.tail = node, None => self.tail = node,
@ -192,7 +192,7 @@ impl<T> LinkedList<T> {
unsafe { unsafe {
node.next = None; node.next = None;
node.prev = self.tail; node.prev = self.tail;
let node = Some(Shared::from(Box::into_unique(node))); let node = Some(Box::into_raw_non_null(node));
match self.tail { match self.tail {
None => self.head = node, None => self.head = node,
@ -225,7 +225,7 @@ impl<T> LinkedList<T> {
/// ///
/// Warning: this will not check that the provided node belongs to the current list. /// Warning: this will not check that the provided node belongs to the current list.
#[inline] #[inline]
unsafe fn unlink_node(&mut self, mut node: Shared<Node<T>>) { unsafe fn unlink_node(&mut self, mut node: NonNull<Node<T>>) {
let node = node.as_mut(); let node = node.as_mut();
match node.prev { match node.prev {
@ -986,11 +986,11 @@ impl<'a, T> IterMut<'a, T> {
Some(prev) => prev, Some(prev) => prev,
}; };
let node = Some(Shared::from(Box::into_unique(box Node { let node = Some(Box::into_raw_non_null(box Node {
next: Some(head), next: Some(head),
prev: Some(prev), prev: Some(prev),
element, element,
}))); }));
prev.as_mut().next = node; prev.as_mut().next = node;
head.as_mut().prev = node; head.as_mut().prev = node;
@ -1038,7 +1038,7 @@ pub struct DrainFilter<'a, T: 'a, F: 'a>
where F: FnMut(&mut T) -> bool, where F: FnMut(&mut T) -> bool,
{ {
list: &'a mut LinkedList<T>, list: &'a mut LinkedList<T>,
it: Option<Shared<Node<T>>>, it: Option<NonNull<Node<T>>>,
pred: F, pred: F,
idx: usize, idx: usize,
old_len: usize, old_len: usize,

View File

@ -322,7 +322,7 @@ impl<T, A: Alloc> RawVec<T, A> {
// would cause overflow // would cause overflow
let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 }; let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 };
match self.a.alloc_array::<T>(new_cap) { match self.a.alloc_array::<T>(new_cap) {
Ok(ptr) => (new_cap, ptr), Ok(ptr) => (new_cap, ptr.into()),
Err(e) => self.a.oom(e), Err(e) => self.a.oom(e),
} }
} }

View File

@ -256,7 +256,7 @@ use core::marker::{Unsize, PhantomData};
use core::mem::{self, align_of_val, forget, size_of_val, uninitialized}; use core::mem::{self, align_of_val, forget, size_of_val, uninitialized};
use core::ops::Deref; use core::ops::Deref;
use core::ops::CoerceUnsized; use core::ops::CoerceUnsized;
use core::ptr::{self, Shared}; use core::ptr::{self, NonNull};
use core::convert::From; use core::convert::From;
use heap::{Heap, Alloc, Layout, box_free}; use heap::{Heap, Alloc, Layout, box_free};
@ -282,7 +282,7 @@ struct RcBox<T: ?Sized> {
/// [get_mut]: #method.get_mut /// [get_mut]: #method.get_mut
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct Rc<T: ?Sized> { pub struct Rc<T: ?Sized> {
ptr: Shared<RcBox<T>>, ptr: NonNull<RcBox<T>>,
phantom: PhantomData<T>, phantom: PhantomData<T>,
} }
@ -311,11 +311,11 @@ impl<T> Rc<T> {
// pointers, which ensures that the weak destructor never frees // pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even // the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one. // if the weak pointer is stored inside the strong one.
ptr: Shared::from(Box::into_unique(box RcBox { ptr: Box::into_raw_non_null(box RcBox {
strong: Cell::new(1), strong: Cell::new(1),
weak: Cell::new(1), weak: Cell::new(1),
value, value,
})), }),
phantom: PhantomData, phantom: PhantomData,
} }
} }
@ -428,7 +428,7 @@ impl<T: ?Sized> Rc<T> {
let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset));
Rc { Rc {
ptr: Shared::new_unchecked(rc_ptr), ptr: NonNull::new_unchecked(rc_ptr),
phantom: PhantomData, phantom: PhantomData,
} }
} }
@ -649,7 +649,7 @@ impl Rc<Any> {
let raw: *const RcBox<Any> = self.ptr.as_ptr(); let raw: *const RcBox<Any> = self.ptr.as_ptr();
forget(self); forget(self);
Ok(Rc { Ok(Rc {
ptr: Shared::new_unchecked(raw as *const RcBox<T> as *mut _), ptr: NonNull::new_unchecked(raw as *const RcBox<T> as *mut _),
phantom: PhantomData, phantom: PhantomData,
}) })
} }
@ -695,7 +695,7 @@ impl<T: ?Sized> Rc<T> {
// Free the allocation without dropping its contents // Free the allocation without dropping its contents
box_free(bptr); box_free(bptr);
Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
} }
} }
} }
@ -722,7 +722,7 @@ impl<T> Rc<[T]> {
&mut (*ptr).value as *mut [T] as *mut T, &mut (*ptr).value as *mut [T] as *mut T,
v.len()); v.len());
Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
} }
} }
@ -781,7 +781,7 @@ impl<T: Clone> RcFromSlice<T> for Rc<[T]> {
// All clear. Forget the guard so it doesn't free the new RcBox. // All clear. Forget the guard so it doesn't free the new RcBox.
forget(guard); forget(guard);
Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData }
} }
} }
} }
@ -1160,7 +1160,7 @@ impl<T> From<Vec<T>> for Rc<[T]> {
/// [`None`]: ../../std/option/enum.Option.html#variant.None /// [`None`]: ../../std/option/enum.Option.html#variant.None
#[stable(feature = "rc_weak", since = "1.4.0")] #[stable(feature = "rc_weak", since = "1.4.0")]
pub struct Weak<T: ?Sized> { pub struct Weak<T: ?Sized> {
ptr: Shared<RcBox<T>>, ptr: NonNull<RcBox<T>>,
} }
#[stable(feature = "rc_weak", since = "1.4.0")] #[stable(feature = "rc_weak", since = "1.4.0")]
@ -1190,11 +1190,11 @@ impl<T> Weak<T> {
pub fn new() -> Weak<T> { pub fn new() -> Weak<T> {
unsafe { unsafe {
Weak { Weak {
ptr: Shared::from(Box::into_unique(box RcBox { ptr: Box::into_raw_non_null(box RcBox {
strong: Cell::new(0), strong: Cell::new(0),
weak: Cell::new(1), weak: Cell::new(1),
value: uninitialized(), value: uninitialized(),
})), }),
} }
} }
} }

View File

@ -78,7 +78,7 @@ use core::num::Float;
use core::ops::{InPlace, Index, IndexMut, Place, Placer}; use core::ops::{InPlace, Index, IndexMut, Place, Placer};
use core::ops; use core::ops;
use core::ptr; use core::ptr;
use core::ptr::Shared; use core::ptr::NonNull;
use core::slice; use core::slice;
use borrow::ToOwned; use borrow::ToOwned;
@ -1124,7 +1124,7 @@ impl<T> Vec<T> {
tail_start: end, tail_start: end,
tail_len: len - end, tail_len: len - end,
iter: range_slice.iter(), iter: range_slice.iter(),
vec: Shared::from(self), vec: NonNull::from(self),
} }
} }
} }
@ -1745,7 +1745,7 @@ impl<T> IntoIterator for Vec<T> {
let cap = self.buf.cap(); let cap = self.buf.cap();
mem::forget(self); mem::forget(self);
IntoIter { IntoIter {
buf: Shared::new_unchecked(begin), buf: NonNull::new_unchecked(begin),
phantom: PhantomData, phantom: PhantomData,
cap, cap,
ptr: begin, ptr: begin,
@ -2267,7 +2267,7 @@ impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
/// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html /// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> { pub struct IntoIter<T> {
buf: Shared<T>, buf: NonNull<T>,
phantom: PhantomData<T>, phantom: PhantomData<T>,
cap: usize, cap: usize,
ptr: *const T, ptr: *const T,
@ -2442,7 +2442,7 @@ pub struct Drain<'a, T: 'a> {
tail_len: usize, tail_len: usize,
/// Current remaining range to remove /// Current remaining range to remove
iter: slice::Iter<'a, T>, iter: slice::Iter<'a, T>,
vec: Shared<Vec<T>>, vec: NonNull<Vec<T>>,
} }
#[stable(feature = "collection_debug", since = "1.17.0")] #[stable(feature = "collection_debug", since = "1.17.0")]

View File

@ -23,7 +23,7 @@ use core::iter::{repeat, FromIterator, FusedIterator};
use core::mem; use core::mem;
use core::ops::{Index, IndexMut, Place, Placer, InPlace}; use core::ops::{Index, IndexMut, Place, Placer, InPlace};
use core::ptr; use core::ptr;
use core::ptr::Shared; use core::ptr::NonNull;
use core::slice; use core::slice;
use core::hash::{Hash, Hasher}; use core::hash::{Hash, Hasher};
@ -895,7 +895,7 @@ impl<T> VecDeque<T> {
self.head = drain_tail; self.head = drain_tail;
Drain { Drain {
deque: Shared::from(&mut *self), deque: NonNull::from(&mut *self),
after_tail: drain_head, after_tail: drain_head,
after_head: head, after_head: head,
iter: Iter { iter: Iter {
@ -2154,7 +2154,7 @@ pub struct Drain<'a, T: 'a> {
after_tail: usize, after_tail: usize,
after_head: usize, after_head: usize,
iter: Iter<'a, T>, iter: Iter<'a, T>,
deque: Shared<VecDeque<T>>, deque: NonNull<VecDeque<T>>,
} }
#[stable(feature = "collection_debug", since = "1.17.0")] #[stable(feature = "collection_debug", since = "1.17.0")]

View File

@ -2321,7 +2321,7 @@ impl<T: ?Sized> PartialOrd for *mut T {
/// its owning Unique. /// its owning Unique.
/// ///
/// If you're uncertain of whether it's correct to use `Unique` for your purposes, /// If you're uncertain of whether it's correct to use `Unique` for your purposes,
/// consider using `Shared`, which has weaker semantics. /// consider using `NonNull`, which has weaker semantics.
/// ///
/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
/// is never dereferenced. This is so that enums may use this forbidden value /// is never dereferenced. This is so that enums may use this forbidden value
@ -2330,9 +2330,9 @@ impl<T: ?Sized> PartialOrd for *mut T {
/// ///
/// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct /// Unlike `*mut T`, `Unique<T>` is covariant over `T`. This should always be correct
/// for any type which upholds Unique's aliasing requirements. /// for any type which upholds Unique's aliasing requirements.
#[allow(missing_debug_implementations)] #[unstable(feature = "ptr_internals", issue = "0",
#[unstable(feature = "unique", reason = "needs an RFC to flesh out design", reason = "use NonNull instead and consider PhantomData<T> \
issue = "27730")] (if you also use #[may_dangle]), Send, and/or Sync")]
pub struct Unique<T: ?Sized> { pub struct Unique<T: ?Sized> {
pointer: NonZero<*const T>, pointer: NonZero<*const T>,
// NOTE: this marker has no consequences for variance, but is necessary // NOTE: this marker has no consequences for variance, but is necessary
@ -2343,26 +2343,34 @@ pub struct Unique<T: ?Sized> {
_marker: PhantomData<T>, _marker: PhantomData<T>,
} }
#[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> fmt::Debug for Unique<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
/// `Unique` pointers are `Send` if `T` is `Send` because the data they /// `Unique` pointers are `Send` if `T` is `Send` because the data they
/// reference is unaliased. Note that this aliasing invariant is /// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the /// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it. /// `Unique` must enforce it.
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
unsafe impl<T: Send + ?Sized> Send for Unique<T> { } unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they
/// reference is unaliased. Note that this aliasing invariant is /// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the /// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it. /// `Unique` must enforce it.
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { } unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<T: Sized> Unique<T> { impl<T: Sized> Unique<T> {
/// Creates a new `Unique` that is dangling, but well-aligned. /// Creates a new `Unique` that is dangling, but well-aligned.
/// ///
/// This is useful for initializing types which lazily allocate, like /// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does. /// `Vec::new` does.
// FIXME: rename to dangling() to match NonNull?
pub fn empty() -> Self { pub fn empty() -> Self {
unsafe { unsafe {
let ptr = mem::align_of::<T>() as *mut T; let ptr = mem::align_of::<T>() as *mut T;
@ -2371,14 +2379,13 @@ impl<T: Sized> Unique<T> {
} }
} }
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> Unique<T> { impl<T: ?Sized> Unique<T> {
/// Creates a new `Unique`. /// Creates a new `Unique`.
/// ///
/// # Safety /// # Safety
/// ///
/// `ptr` must be non-null. /// `ptr` must be non-null.
#[unstable(feature = "unique", issue = "27730")]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData } Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
} }
@ -2397,7 +2404,7 @@ impl<T: ?Sized> Unique<T> {
/// ///
/// The resulting lifetime is bound to self so this behaves "as if" /// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer /// it were actually an instance of T that is getting borrowed. If a longer
/// (unbound) lifetime is needed, use `&*my_ptr.ptr()`. /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
pub unsafe fn as_ref(&self) -> &T { pub unsafe fn as_ref(&self) -> &T {
&*self.as_ptr() &*self.as_ptr()
} }
@ -2406,112 +2413,130 @@ impl<T: ?Sized> Unique<T> {
/// ///
/// The resulting lifetime is bound to self so this behaves "as if" /// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer /// it were actually an instance of T that is getting borrowed. If a longer
/// (unbound) lifetime is needed, use `&mut *my_ptr.ptr()`. /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
pub unsafe fn as_mut(&mut self) -> &mut T { pub unsafe fn as_mut(&mut self) -> &mut T {
&mut *self.as_ptr() &mut *self.as_ptr()
} }
} }
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> Clone for Unique<T> { impl<T: ?Sized> Clone for Unique<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
*self *self
} }
} }
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> Copy for Unique<T> { } impl<T: ?Sized> Copy for Unique<T> { }
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { } impl<T: ?Sized, U: ?Sized> CoerceUnsized<Unique<U>> for Unique<T> where T: Unsize<U> { }
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<T: ?Sized> fmt::Pointer for Unique<T> { impl<T: ?Sized> fmt::Pointer for Unique<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.as_ptr(), f) fmt::Pointer::fmt(&self.as_ptr(), f)
} }
} }
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> { impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
fn from(reference: &'a mut T) -> Self { fn from(reference: &'a mut T) -> Self {
Unique { pointer: NonZero::from(reference), _marker: PhantomData } Unique { pointer: NonZero::from(reference), _marker: PhantomData }
} }
} }
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<&'a T> for Unique<T> { impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
fn from(reference: &'a T) -> Self { fn from(reference: &'a T) -> Self {
Unique { pointer: NonZero::from(reference), _marker: PhantomData } Unique { pointer: NonZero::from(reference), _marker: PhantomData }
} }
} }
#[unstable(feature = "ptr_internals", issue = "0")]
impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
fn from(p: NonNull<T>) -> Self {
Unique { pointer: p.pointer, _marker: PhantomData }
}
}
/// Previous name of `NonNull`.
#[rustc_deprecated(since = "1.24", reason = "renamed to `NonNull`")]
#[unstable(feature = "shared", issue = "27730")]
pub type Shared<T> = NonNull<T>;
/// `*mut T` but non-zero and covariant. /// `*mut T` but non-zero and covariant.
/// ///
/// This is often the correct thing to use when building data structures using /// This is often the correct thing to use when building data structures using
/// raw pointers, but is ultimately more dangerous to use because of its additional /// raw pointers, but is ultimately more dangerous to use because of its additional
/// properties. If you're not sure if you should use `Shared<T>`, just use `*mut T`! /// properties. If you're not sure if you should use `NonNull<T>`, just use `*mut T`!
/// ///
/// Unlike `*mut T`, the pointer must always be non-null, even if the pointer /// Unlike `*mut T`, the pointer must always be non-null, even if the pointer
/// is never dereferenced. This is so that enums may use this forbidden value /// is never dereferenced. This is so that enums may use this forbidden value
/// as a discriminant -- `Option<Shared<T>>` has the same size as `Shared<T>`. /// as a discriminant -- `Option<NonNull<T>>` has the same size as `NonNull<T>`.
/// However the pointer may still dangle if it isn't dereferenced. /// However the pointer may still dangle if it isn't dereferenced.
/// ///
/// Unlike `*mut T`, `Shared<T>` is covariant over `T`. If this is incorrect /// Unlike `*mut T`, `NonNull<T>` is covariant over `T`. If this is incorrect
/// for your use case, you should include some PhantomData in your type to /// for your use case, you should include some PhantomData in your type to
/// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`. /// provide invariance, such as `PhantomData<Cell<T>>` or `PhantomData<&'a mut T>`.
/// Usually this won't be necessary; covariance is correct for most safe abstractions, /// Usually this won't be necessary; covariance is correct for most safe abstractions,
/// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they /// such as Box, Rc, Arc, Vec, and LinkedList. This is the case because they
/// provide a public API that follows the normal shared XOR mutable rules of Rust. /// provide a public API that follows the normal shared XOR mutable rules of Rust.
#[allow(missing_debug_implementations)] #[stable(feature = "nonnull", since = "1.24.0")]
#[unstable(feature = "shared", reason = "needs an RFC to flesh out design", pub struct NonNull<T: ?Sized> {
issue = "27730")]
pub struct Shared<T: ?Sized> {
pointer: NonZero<*const T>, pointer: NonZero<*const T>,
} }
/// `Shared` pointers are not `Send` because the data they reference may be aliased. #[stable(feature = "nonnull", since = "1.24.0")]
// NB: This impl is unnecessary, but should provide better error messages. impl<T: ?Sized> fmt::Debug for NonNull<T> {
#[unstable(feature = "shared", issue = "27730")] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
impl<T: ?Sized> !Send for Shared<T> { } fmt::Pointer::fmt(&self.as_ptr(), f)
}
}
/// `Shared` pointers are not `Sync` because the data they reference may be aliased. /// `NonNull` pointers are not `Send` because the data they reference may be aliased.
// NB: This impl is unnecessary, but should provide better error messages. // NB: This impl is unnecessary, but should provide better error messages.
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> !Sync for Shared<T> { } impl<T: ?Sized> !Send for NonNull<T> { }
#[unstable(feature = "shared", issue = "27730")] /// `NonNull` pointers are not `Sync` because the data they reference may be aliased.
impl<T: Sized> Shared<T> { // NB: This impl is unnecessary, but should provide better error messages.
/// Creates a new `Shared` that is dangling, but well-aligned. #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> !Sync for NonNull<T> { }
impl<T: Sized> NonNull<T> {
/// Creates a new `NonNull` that is dangling, but well-aligned.
/// ///
/// This is useful for initializing types which lazily allocate, like /// This is useful for initializing types which lazily allocate, like
/// `Vec::new` does. /// `Vec::new` does.
pub fn empty() -> Self { #[stable(feature = "nonnull", since = "1.24.0")]
pub fn dangling() -> Self {
unsafe { unsafe {
let ptr = mem::align_of::<T>() as *mut T; let ptr = mem::align_of::<T>() as *mut T;
Shared::new_unchecked(ptr) NonNull::new_unchecked(ptr)
} }
} }
} }
#[unstable(feature = "shared", issue = "27730")] impl<T: ?Sized> NonNull<T> {
impl<T: ?Sized> Shared<T> { /// Creates a new `NonNull`.
/// Creates a new `Shared`.
/// ///
/// # Safety /// # Safety
/// ///
/// `ptr` must be non-null. /// `ptr` must be non-null.
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
Shared { pointer: NonZero::new_unchecked(ptr) } NonNull { pointer: NonZero::new_unchecked(ptr) }
} }
/// Creates a new `Shared` if `ptr` is non-null. /// Creates a new `NonNull` if `ptr` is non-null.
#[stable(feature = "nonnull", since = "1.24.0")]
pub fn new(ptr: *mut T) -> Option<Self> { pub fn new(ptr: *mut T) -> Option<Self> {
NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz }) NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz })
} }
/// Acquires the underlying `*mut` pointer. /// Acquires the underlying `*mut` pointer.
#[stable(feature = "nonnull", since = "1.24.0")]
pub fn as_ptr(self) -> *mut T { pub fn as_ptr(self) -> *mut T {
self.pointer.get() as *mut T self.pointer.get() as *mut T
} }
@ -2520,7 +2545,8 @@ impl<T: ?Sized> Shared<T> {
/// ///
/// The resulting lifetime is bound to self so this behaves "as if" /// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer /// it were actually an instance of T that is getting borrowed. If a longer
/// (unbound) lifetime is needed, use `&*my_ptr.ptr()`. /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`.
#[stable(feature = "nonnull", since = "1.24.0")]
pub unsafe fn as_ref(&self) -> &T { pub unsafe fn as_ref(&self) -> &T {
&*self.as_ptr() &*self.as_ptr()
} }
@ -2529,56 +2555,50 @@ impl<T: ?Sized> Shared<T> {
/// ///
/// The resulting lifetime is bound to self so this behaves "as if" /// The resulting lifetime is bound to self so this behaves "as if"
/// it were actually an instance of T that is getting borrowed. If a longer /// it were actually an instance of T that is getting borrowed. If a longer
/// (unbound) lifetime is needed, use `&mut *my_ptr.ptr_mut()`. /// (unbound) lifetime is needed, use `&mut *my_ptr.as_ptr()`.
#[stable(feature = "nonnull", since = "1.24.0")]
pub unsafe fn as_mut(&mut self) -> &mut T { pub unsafe fn as_mut(&mut self) -> &mut T {
&mut *self.as_ptr() &mut *self.as_ptr()
} }
/// Acquires the underlying pointer as a `*mut` pointer.
#[rustc_deprecated(since = "1.19", reason = "renamed to `as_ptr` for ergonomics/consistency")]
#[unstable(feature = "shared", issue = "27730")]
pub unsafe fn as_mut_ptr(&self) -> *mut T {
self.as_ptr()
}
} }
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> Clone for Shared<T> { impl<T: ?Sized> Clone for NonNull<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
*self *self
} }
} }
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> Copy for Shared<T> { } impl<T: ?Sized> Copy for NonNull<T> { }
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Shared<U>> for Shared<T> where T: Unsize<U> { } impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> fmt::Pointer for Shared<T> { impl<T: ?Sized> fmt::Pointer for NonNull<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Pointer::fmt(&self.as_ptr(), f) fmt::Pointer::fmt(&self.as_ptr(), f)
} }
} }
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> From<Unique<T>> for Shared<T> { impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
fn from(unique: Unique<T>) -> Self { fn from(unique: Unique<T>) -> Self {
Shared { pointer: unique.pointer } NonNull { pointer: unique.pointer }
} }
} }
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<'a, T: ?Sized> From<&'a mut T> for Shared<T> { impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
fn from(reference: &'a mut T) -> Self { fn from(reference: &'a mut T) -> Self {
Shared { pointer: NonZero::from(reference) } NonNull { pointer: NonZero::from(reference) }
} }
} }
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<'a, T: ?Sized> From<&'a T> for Shared<T> { impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
fn from(reference: &'a T) -> Self { fn from(reference: &'a T) -> Self {
Shared { pointer: NonZero::from(reference) } NonNull { pointer: NonZero::from(reference) }
} }
} }

View File

@ -41,7 +41,6 @@
#![feature(trusted_len)] #![feature(trusted_len)]
#![feature(try_from)] #![feature(try_from)]
#![feature(try_trait)] #![feature(try_trait)]
#![feature(unique)]
#![feature(exact_chunks)] #![feature(exact_chunks)]
extern crate core; extern crate core;

View File

@ -249,9 +249,9 @@ fn test_set_memory() {
} }
#[test] #[test]
fn test_unsized_unique() { fn test_unsized_nonnull() {
let xs: &[i32] = &[1, 2, 3]; let xs: &[i32] = &[1, 2, 3];
let ptr = unsafe { Unique::new_unchecked(xs as *const [i32] as *mut [i32]) }; let ptr = unsafe { NonNull::new_unchecked(xs as *const [i32] as *mut [i32]) };
let ys = unsafe { ptr.as_ref() }; let ys = unsafe { ptr.as_ref() };
let zs: &[i32] = &[1, 2, 3]; let zs: &[i32] = &[1, 2, 3];
assert!(ys == zs); assert!(ys == zs);

View File

@ -12,7 +12,7 @@
use std::marker::Unsize; use std::marker::Unsize;
use std::iter::Extend; use std::iter::Extend;
use std::ptr::{self, drop_in_place, Shared}; use std::ptr::{self, drop_in_place, NonNull};
use std::ops::{Deref, DerefMut, Range}; use std::ops::{Deref, DerefMut, Range};
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::slice; use std::slice;
@ -146,7 +146,7 @@ impl<A: Array> ArrayVec<A> {
tail_start: end, tail_start: end,
tail_len: len - end, tail_len: len - end,
iter: range_slice.iter(), iter: range_slice.iter(),
array_vec: Shared::from(self), array_vec: NonNull::from(self),
} }
} }
} }
@ -232,7 +232,7 @@ pub struct Drain<'a, A: Array>
tail_start: usize, tail_start: usize,
tail_len: usize, tail_len: usize,
iter: slice::Iter<'a, ManuallyDrop<A::Element>>, iter: slice::Iter<'a, ManuallyDrop<A::Element>>,
array_vec: Shared<ArrayVec<A>>, array_vec: NonNull<ArrayVec<A>>,
} }
impl<'a, A: Array> Iterator for Drain<'a, A> { impl<'a, A: Array> Iterator for Drain<'a, A> {

View File

@ -21,7 +21,6 @@
html_root_url = "https://doc.rust-lang.org/nightly/")] html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(warnings)] #![deny(warnings)]
#![feature(shared)]
#![feature(collections_range)] #![feature(collections_range)]
#![feature(nonzero)] #![feature(nonzero)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]

View File

@ -16,7 +16,7 @@ use marker;
use mem::{align_of, size_of, needs_drop}; use mem::{align_of, size_of, needs_drop};
use mem; use mem;
use ops::{Deref, DerefMut}; use ops::{Deref, DerefMut};
use ptr::{self, Unique, Shared}; use ptr::{self, Unique, NonNull};
use self::BucketState::*; use self::BucketState::*;
@ -873,7 +873,7 @@ impl<K, V> RawTable<K, V> {
elems_left, elems_left,
marker: marker::PhantomData, marker: marker::PhantomData,
}, },
table: Shared::from(self), table: NonNull::from(self),
marker: marker::PhantomData, marker: marker::PhantomData,
} }
} }
@ -1020,7 +1020,7 @@ impl<K, V> IntoIter<K, V> {
/// Iterator over the entries in a table, clearing the table. /// Iterator over the entries in a table, clearing the table.
pub struct Drain<'a, K: 'a, V: 'a> { pub struct Drain<'a, K: 'a, V: 'a> {
table: Shared<RawTable<K, V>>, table: NonNull<RawTable<K, V>>,
iter: RawBuckets<'static, K, V>, iter: RawBuckets<'static, K, V>,
marker: marker::PhantomData<&'a RawTable<K, V>>, marker: marker::PhantomData<&'a RawTable<K, V>>,
} }

View File

@ -293,11 +293,11 @@
#![feature(placement_in_syntax)] #![feature(placement_in_syntax)]
#![feature(placement_new_protocol)] #![feature(placement_new_protocol)]
#![feature(prelude_import)] #![feature(prelude_import)]
#![feature(ptr_internals)]
#![feature(rand)] #![feature(rand)]
#![feature(raw)] #![feature(raw)]
#![feature(repr_align)] #![feature(repr_align)]
#![feature(rustc_attrs)] #![feature(rustc_attrs)]
#![feature(shared)]
#![feature(sip_hash_13)] #![feature(sip_hash_13)]
#![feature(slice_bytes)] #![feature(slice_bytes)]
#![feature(slice_concat_ext)] #![feature(slice_concat_ext)]
@ -315,7 +315,6 @@
#![feature(try_from)] #![feature(try_from)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(unicode)] #![feature(unicode)]
#![feature(unique)]
#![feature(untagged_unions)] #![feature(untagged_unions)]
#![feature(unwind_attributes)] #![feature(unwind_attributes)]
#![feature(vec_push_all)] #![feature(vec_push_all)]

View File

@ -17,7 +17,7 @@ use cell::UnsafeCell;
use fmt; use fmt;
use ops::{Deref, DerefMut}; use ops::{Deref, DerefMut};
use panicking; use panicking;
use ptr::{Unique, Shared}; use ptr::{Unique, NonNull};
use rc::Rc; use rc::Rc;
use sync::{Arc, Mutex, RwLock, atomic}; use sync::{Arc, Mutex, RwLock, atomic};
use thread::Result; use thread::Result;
@ -196,10 +196,10 @@ impl<'a, T: RefUnwindSafe + ?Sized> UnwindSafe for &'a T {}
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {} impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
#[stable(feature = "catch_unwind", since = "1.9.0")] #[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {} impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
#[unstable(feature = "unique", issue = "27730")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {} impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for Shared<T> {} impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")] #[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> UnwindSafe for Mutex<T> {} impl<T: ?Sized> UnwindSafe for Mutex<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")] #[stable(feature = "catch_unwind", since = "1.9.0")]

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![feature(allocator_api, unique)] #![feature(allocator_api, nonnull)]
use std::heap::{Heap, Alloc}; use std::heap::{Heap, Alloc};

View File

@ -10,13 +10,11 @@
// Don't fail if we encounter a NonZero<*T> where T is an unsized type // Don't fail if we encounter a NonZero<*T> where T is an unsized type
#![feature(unique)] use std::ptr::NonNull;
use std::ptr::Unique;
fn main() { fn main() {
let mut a = [0u8; 5]; let mut a = [0u8; 5];
let b: Option<Unique<[u8]>> = Some(Unique::from(&mut a)); let b: Option<NonNull<[u8]>> = Some(NonNull::from(&mut a));
match b { match b {
Some(_) => println!("Got `Some`"), Some(_) => println!("Got `Some`"),
None => panic!("Unexpected `None`"), None => panic!("Unexpected `None`"),

View File

@ -15,7 +15,6 @@ const EXPECTED = {
{ 'path': 'std::char', 'name': 'from_u32' }, { 'path': 'std::char', 'name': 'from_u32' },
{ 'path': 'std::str', 'name': 'from_utf8' }, { 'path': 'std::str', 'name': 'from_utf8' },
{ 'path': 'std::string::String', 'name': 'from_utf8' }, { 'path': 'std::string::String', 'name': 'from_utf8' },
{ 'path': 'std::boxed::Box', 'name': 'from_unique' },
{ 'path': 'std::i32', 'name': 'from_unsigned' }, { 'path': 'std::i32', 'name': 'from_unsigned' },
{ 'path': 'std::i128', 'name': 'from_unsigned' }, { 'path': 'std::i128', 'name': 'from_unsigned' },
], ],