diff --git a/src/doc/nomicon b/src/doc/nomicon index 2f7b05fd5939a..fec3182d0b0a3 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 2f7b05fd5939aa49d52c4ab309b9a47776ba7bd8 +Subproject commit fec3182d0b0a3cf8122e192b3270064a5b19be5b diff --git a/src/liballoc/allocator.rs b/src/liballoc/allocator.rs index c2a8f5f8ff957..55e8c0b430f52 100644 --- a/src/liballoc/allocator.rs +++ b/src/liballoc/allocator.rs @@ -19,7 +19,7 @@ use core::cmp; use core::fmt; use core::mem; use core::usize; -use core::ptr::{self, Unique}; +use core::ptr::{self, NonNull}; /// Represents the combination of a starting address and /// a total capacity of the returned block. @@ -895,12 +895,12 @@ pub unsafe trait Alloc { /// Clients wishing to abort computation in response to an /// allocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. - fn alloc_one(&mut self) -> Result, AllocErr> + fn alloc_one(&mut self) -> Result, AllocErr> where Self: Sized { let k = Layout::new::(); 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 { 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 /// /// * the layout of `T` must *fit* that block of memory. - unsafe fn dealloc_one(&mut self, ptr: Unique) + unsafe fn dealloc_one(&mut self, ptr: NonNull) where Self: Sized { 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 /// allocation error are encouraged to call the allocator's `oom` /// method, rather than directly invoking `panic!` or similar. - fn alloc_array(&mut self, n: usize) -> Result, AllocErr> + fn alloc_array(&mut self, n: usize) -> Result, AllocErr> where Self: Sized { match Layout::array::(n) { @@ -971,7 +971,7 @@ pub unsafe trait Alloc { unsafe { self.alloc(layout.clone()) .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` /// method, rather than directly invoking `panic!` or similar. unsafe fn realloc_array(&mut self, - ptr: Unique, + ptr: NonNull, n_old: usize, - n_new: usize) -> Result, AllocErr> + n_new: usize) -> Result, AllocErr> where Self: Sized { match (Layout::array::(n_old), Layout::array::(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_unchecked(p as *mut T)) + .map(|p| NonNull::new_unchecked(p as *mut T)) } _ => { Err(AllocErr::invalid_input("invalid layout for realloc_array")) @@ -1048,7 +1048,7 @@ pub unsafe trait Alloc { /// constraints. /// /// Always returns `Err` on arithmetic overflow. - unsafe fn dealloc_array(&mut self, ptr: Unique, n: usize) -> Result<(), AllocErr> + unsafe fn dealloc_array(&mut self, ptr: NonNull, n: usize) -> Result<(), AllocErr> where Self: Sized { let raw_ptr = ptr.as_ptr() as *mut u8; diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 185af8835d1e4..6a77bf64baee5 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -25,7 +25,7 @@ use core::intrinsics::abort; use core::mem::{self, align_of_val, size_of_val, uninitialized}; use core::ops::Deref; use core::ops::CoerceUnsized; -use core::ptr::{self, Shared}; +use core::ptr::{self, NonNull}; use core::marker::{Unsize, PhantomData}; use core::hash::{Hash, Hasher}; use core::{isize, usize}; @@ -197,7 +197,7 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize; /// [rc_examples]: ../../std/rc/index.html#examples #[stable(feature = "rust1", since = "1.0.0")] pub struct Arc { - ptr: Shared>, + ptr: NonNull>, phantom: PhantomData, } @@ -234,7 +234,7 @@ impl, U: ?Sized> CoerceUnsized> for Arc {} /// [`None`]: ../../std/option/enum.Option.html#variant.None #[stable(feature = "arc_weak", since = "1.4.0")] pub struct Weak { - ptr: Shared>, + ptr: NonNull>, } #[stable(feature = "arc_weak", since = "1.4.0")] @@ -286,7 +286,7 @@ impl Arc { weak: atomic::AtomicUsize::new(1), 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. @@ -397,7 +397,7 @@ impl Arc { let arc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); Arc { - ptr: Shared::new_unchecked(arc_ptr), + ptr: NonNull::new_unchecked(arc_ptr), phantom: PhantomData, } } @@ -582,7 +582,7 @@ impl Arc { // Free the allocation without dropping its contents box_free(bptr); - Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } } @@ -609,7 +609,7 @@ impl Arc<[T]> { &mut (*ptr).data as *mut [T] as *mut T, v.len()); - Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } @@ -669,7 +669,7 @@ impl ArcFromSlice for Arc<[T]> { // All clear. Forget the guard so it doesn't free the new ArcInner. mem::forget(guard); - Arc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Arc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } } @@ -991,11 +991,11 @@ impl Weak { pub fn new() -> Weak { unsafe { Weak { - ptr: Shared::from(Box::into_unique(box ArcInner { + ptr: Box::into_raw_non_null(box ArcInner { strong: atomic::AtomicUsize::new(0), weak: atomic::AtomicUsize::new(1), data: uninitialized(), - })), + }), } } } diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 6f125cdba8190..bfe23ddeca328 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -68,7 +68,7 @@ use core::marker::{self, Unsize}; use core::mem; use core::ops::{CoerceUnsized, Deref, DerefMut, Generator, GeneratorState}; use core::ops::{BoxPlace, Boxed, InPlace, Place, Placer}; -use core::ptr::{self, Unique}; +use core::ptr::{self, NonNull, Unique}; use core::convert::From; use str::from_boxed_utf8_unchecked; @@ -269,38 +269,7 @@ impl Box { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub unsafe fn from_raw(raw: *mut T) -> Self { - Box::from_unique(Unique::new_unchecked(raw)) - } - - /// Constructs a `Box` from a `Unique` 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` 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) -> Self { - Box(u) + Box(Unique::new_unchecked(raw)) } /// Consumes the `Box`, returning the wrapped raw pointer. @@ -326,40 +295,42 @@ impl Box { #[stable(feature = "box_raw", since = "1.4.0")] #[inline] pub fn into_raw(b: Box) -> *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`. + /// Consumes the `Box`, returning the wrapped pointer as `NonNull`. /// /// 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 either convert the `Unique` pointer: - /// - /// - Into a `Box` with the [`Box::from_unique`] function. - /// - /// - Into a raw pointer and back into a `Box` with the [`Box::from_raw`] - /// function. + /// proper way to do so is to convert the `NonNull` pointer + /// 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 - /// 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. /// - /// [`Box::from_unique`]: struct.Box.html#method.from_unique /// [`Box::from_raw`]: struct.Box.html#method.from_raw /// /// # Examples /// /// ``` - /// #![feature(unique)] + /// #![feature(box_into_raw_non_null)] /// /// fn main() { /// 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", - issue = "27730")] + #[unstable(feature = "box_into_raw_non_null", issue = "47336")] + #[inline] + pub fn into_raw_non_null(b: Box) -> NonNull { + Box::into_unique(b).into() + } + + #[unstable(feature = "ptr_internals", issue = "0", reason = "use into_raw_non_null instead")] #[inline] pub fn into_unique(b: Box) -> Unique { let unique = b.0; diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs index b2bd9d7d8fafa..37af9ea529532 100644 --- a/src/liballoc/heap.rs +++ b/src/liballoc/heap.rs @@ -232,7 +232,7 @@ unsafe impl Alloc for Heap { /// /// This preserves the non-null invariant for types like `Box`. The address /// 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")] pub const EMPTY: *mut () = 1 as *mut (); diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 6ee4f802802ab..5139e54b5604a 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -84,6 +84,7 @@ #![cfg_attr(test, feature(rand, test))] #![feature(allow_internal_unstable)] #![feature(ascii_ctype)] +#![feature(box_into_raw_non_null)] #![feature(box_patterns)] #![feature(box_syntax)] #![feature(cfg_target_has_atomic)] @@ -109,8 +110,8 @@ #![feature(pattern)] #![feature(placement_in_syntax)] #![feature(placement_new_protocol)] +#![feature(ptr_internals)] #![feature(rustc_attrs)] -#![feature(shared)] #![feature(slice_get_slice)] #![feature(slice_patterns)] #![feature(slice_rsplit)] @@ -120,7 +121,6 @@ #![feature(trusted_len)] #![feature(unboxed_closures)] #![feature(unicode)] -#![feature(unique)] #![feature(unsize)] #![feature(allocator_internals)] #![feature(on_unimplemented)] diff --git a/src/liballoc/linked_list.rs b/src/liballoc/linked_list.rs index 3ac5a85d721a1..3cc810a055f3e 100644 --- a/src/liballoc/linked_list.rs +++ b/src/liballoc/linked_list.rs @@ -29,7 +29,7 @@ use core::iter::{FromIterator, FusedIterator}; use core::marker::PhantomData; use core::mem; use core::ops::{BoxPlace, InPlace, Place, Placer}; -use core::ptr::{self, Shared}; +use core::ptr::{self, NonNull}; use boxed::{Box, IntermediateBox}; use super::SpecExtend; @@ -44,15 +44,15 @@ use super::SpecExtend; /// more memory efficient and make better use of CPU cache. #[stable(feature = "rust1", since = "1.0.0")] pub struct LinkedList { - head: Option>>, - tail: Option>>, + head: Option>>, + tail: Option>>, len: usize, marker: PhantomData>>, } struct Node { - next: Option>>, - prev: Option>>, + next: Option>>, + prev: Option>>, element: T, } @@ -65,8 +65,8 @@ struct Node { /// [`LinkedList`]: struct.LinkedList.html #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T: 'a> { - head: Option>>, - tail: Option>>, + head: Option>>, + tail: Option>>, len: usize, marker: PhantomData<&'a Node>, } @@ -98,8 +98,8 @@ impl<'a, T> Clone for Iter<'a, T> { #[stable(feature = "rust1", since = "1.0.0")] pub struct IterMut<'a, T: 'a> { list: &'a mut LinkedList, - head: Option>>, - tail: Option>>, + head: Option>>, + tail: Option>>, len: usize, } @@ -157,7 +157,7 @@ impl LinkedList { unsafe { node.next = self.head; node.prev = None; - let node = Some(Shared::from(Box::into_unique(node))); + let node = Some(Box::into_raw_non_null(node)); match self.head { None => self.tail = node, @@ -192,7 +192,7 @@ impl LinkedList { unsafe { node.next = None; 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 { None => self.head = node, @@ -225,7 +225,7 @@ impl LinkedList { /// /// Warning: this will not check that the provided node belongs to the current list. #[inline] - unsafe fn unlink_node(&mut self, mut node: Shared>) { + unsafe fn unlink_node(&mut self, mut node: NonNull>) { let node = node.as_mut(); match node.prev { @@ -986,11 +986,11 @@ impl<'a, T> IterMut<'a, T> { 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), prev: Some(prev), element, - }))); + })); prev.as_mut().next = node; head.as_mut().prev = node; @@ -1038,7 +1038,7 @@ pub struct DrainFilter<'a, T: 'a, F: 'a> where F: FnMut(&mut T) -> bool, { list: &'a mut LinkedList, - it: Option>>, + it: Option>>, pred: F, idx: usize, old_len: usize, diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs index dbf1fb1367dda..621e190696137 100644 --- a/src/liballoc/raw_vec.rs +++ b/src/liballoc/raw_vec.rs @@ -322,7 +322,7 @@ impl RawVec { // would cause overflow let new_cap = if elem_size > (!0) / 8 { 1 } else { 4 }; match self.a.alloc_array::(new_cap) { - Ok(ptr) => (new_cap, ptr), + Ok(ptr) => (new_cap, ptr.into()), Err(e) => self.a.oom(e), } } diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 59079f9ba76bc..1fa5d34cb5787 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -256,7 +256,7 @@ use core::marker::{Unsize, PhantomData}; use core::mem::{self, align_of_val, forget, size_of_val, uninitialized}; use core::ops::Deref; use core::ops::CoerceUnsized; -use core::ptr::{self, Shared}; +use core::ptr::{self, NonNull}; use core::convert::From; use heap::{Heap, Alloc, Layout, box_free}; @@ -282,7 +282,7 @@ struct RcBox { /// [get_mut]: #method.get_mut #[stable(feature = "rust1", since = "1.0.0")] pub struct Rc { - ptr: Shared>, + ptr: NonNull>, phantom: PhantomData, } @@ -311,11 +311,11 @@ impl Rc { // 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 { + ptr: Box::into_raw_non_null(box RcBox { strong: Cell::new(1), weak: Cell::new(1), value, - })), + }), phantom: PhantomData, } } @@ -428,7 +428,7 @@ impl Rc { let rc_ptr = set_data_ptr(fake_ptr, (ptr as *mut u8).offset(-offset)); Rc { - ptr: Shared::new_unchecked(rc_ptr), + ptr: NonNull::new_unchecked(rc_ptr), phantom: PhantomData, } } @@ -649,7 +649,7 @@ impl Rc { let raw: *const RcBox = self.ptr.as_ptr(); forget(self); Ok(Rc { - ptr: Shared::new_unchecked(raw as *const RcBox as *mut _), + ptr: NonNull::new_unchecked(raw as *const RcBox as *mut _), phantom: PhantomData, }) } @@ -695,7 +695,7 @@ impl Rc { // Free the allocation without dropping its contents box_free(bptr); - Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } } @@ -722,7 +722,7 @@ impl Rc<[T]> { &mut (*ptr).value as *mut [T] as *mut T, v.len()); - Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } @@ -781,7 +781,7 @@ impl RcFromSlice for Rc<[T]> { // All clear. Forget the guard so it doesn't free the new RcBox. forget(guard); - Rc { ptr: Shared::new_unchecked(ptr), phantom: PhantomData } + Rc { ptr: NonNull::new_unchecked(ptr), phantom: PhantomData } } } } @@ -1160,7 +1160,7 @@ impl From> for Rc<[T]> { /// [`None`]: ../../std/option/enum.Option.html#variant.None #[stable(feature = "rc_weak", since = "1.4.0")] pub struct Weak { - ptr: Shared>, + ptr: NonNull>, } #[stable(feature = "rc_weak", since = "1.4.0")] @@ -1190,11 +1190,11 @@ impl Weak { pub fn new() -> Weak { unsafe { Weak { - ptr: Shared::from(Box::into_unique(box RcBox { + ptr: Box::into_raw_non_null(box RcBox { strong: Cell::new(0), weak: Cell::new(1), value: uninitialized(), - })), + }), } } } diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs index 301e44632b823..b14b9d7476548 100644 --- a/src/liballoc/vec.rs +++ b/src/liballoc/vec.rs @@ -78,7 +78,7 @@ use core::num::Float; use core::ops::{InPlace, Index, IndexMut, Place, Placer}; use core::ops; use core::ptr; -use core::ptr::Shared; +use core::ptr::NonNull; use core::slice; use borrow::ToOwned; @@ -1124,7 +1124,7 @@ impl Vec { tail_start: end, tail_len: len - end, iter: range_slice.iter(), - vec: Shared::from(self), + vec: NonNull::from(self), } } } @@ -1745,7 +1745,7 @@ impl IntoIterator for Vec { let cap = self.buf.cap(); mem::forget(self); IntoIter { - buf: Shared::new_unchecked(begin), + buf: NonNull::new_unchecked(begin), phantom: PhantomData, cap, ptr: begin, @@ -2267,7 +2267,7 @@ impl<'a, T> FromIterator for Cow<'a, [T]> where T: Clone { /// [`IntoIterator`]: ../../std/iter/trait.IntoIterator.html #[stable(feature = "rust1", since = "1.0.0")] pub struct IntoIter { - buf: Shared, + buf: NonNull, phantom: PhantomData, cap: usize, ptr: *const T, @@ -2442,7 +2442,7 @@ pub struct Drain<'a, T: 'a> { tail_len: usize, /// Current remaining range to remove iter: slice::Iter<'a, T>, - vec: Shared>, + vec: NonNull>, } #[stable(feature = "collection_debug", since = "1.17.0")] diff --git a/src/liballoc/vec_deque.rs b/src/liballoc/vec_deque.rs index f56aa23a4eb2f..8f05a69c5f3ec 100644 --- a/src/liballoc/vec_deque.rs +++ b/src/liballoc/vec_deque.rs @@ -23,7 +23,7 @@ use core::iter::{repeat, FromIterator, FusedIterator}; use core::mem; use core::ops::{Index, IndexMut, Place, Placer, InPlace}; use core::ptr; -use core::ptr::Shared; +use core::ptr::NonNull; use core::slice; use core::hash::{Hash, Hasher}; @@ -895,7 +895,7 @@ impl VecDeque { self.head = drain_tail; Drain { - deque: Shared::from(&mut *self), + deque: NonNull::from(&mut *self), after_tail: drain_head, after_head: head, iter: Iter { @@ -2154,7 +2154,7 @@ pub struct Drain<'a, T: 'a> { after_tail: usize, after_head: usize, iter: Iter<'a, T>, - deque: Shared>, + deque: NonNull>, } #[stable(feature = "collection_debug", since = "1.17.0")] diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 7f7246df8f2a7..fab5832d905df 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2321,7 +2321,7 @@ impl PartialOrd for *mut T { /// its owning Unique. /// /// 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 /// is never dereferenced. This is so that enums may use this forbidden value @@ -2330,9 +2330,9 @@ impl PartialOrd for *mut T { /// /// Unlike `*mut T`, `Unique` is covariant over `T`. This should always be correct /// for any type which upholds Unique's aliasing requirements. -#[allow(missing_debug_implementations)] -#[unstable(feature = "unique", reason = "needs an RFC to flesh out design", - issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0", + reason = "use NonNull instead and consider PhantomData \ + (if you also use #[may_dangle]), Send, and/or Sync")] pub struct Unique { pointer: NonZero<*const T>, // NOTE: this marker has no consequences for variance, but is necessary @@ -2343,26 +2343,34 @@ pub struct Unique { _marker: PhantomData, } +#[unstable(feature = "ptr_internals", issue = "0")] +impl fmt::Debug for Unique { + 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 /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] unsafe impl Send for Unique { } /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] unsafe impl Sync for Unique { } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl Unique { /// Creates a new `Unique` that is dangling, but well-aligned. /// /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does. + // FIXME: rename to dangling() to match NonNull? pub fn empty() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; @@ -2371,14 +2379,13 @@ impl Unique { } } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl Unique { /// Creates a new `Unique`. /// /// # Safety /// /// `ptr` must be non-null. - #[unstable(feature = "unique", issue = "27730")] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData } } @@ -2397,7 +2404,7 @@ impl Unique { /// /// 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 - /// (unbound) lifetime is needed, use `&*my_ptr.ptr()`. + /// (unbound) lifetime is needed, use `&*my_ptr.as_ptr()`. pub unsafe fn as_ref(&self) -> &T { &*self.as_ptr() } @@ -2406,112 +2413,130 @@ impl Unique { /// /// 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 - /// (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 { &mut *self.as_ptr() } } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl Clone for Unique { fn clone(&self) -> Self { *self } } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl Copy for Unique { } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl CoerceUnsized> for Unique where T: Unsize { } -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl fmt::Pointer for Unique { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 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 { fn from(reference: &'a mut T) -> Self { 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 { fn from(reference: &'a T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } } } +#[unstable(feature = "ptr_internals", issue = "0")] +impl<'a, T: ?Sized> From> for Unique { + fn from(p: NonNull) -> 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 = NonNull; + /// `*mut T` but non-zero and covariant. /// /// 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 -/// properties. If you're not sure if you should use `Shared`, just use `*mut T`! +/// properties. If you're not sure if you should use `NonNull`, just use `*mut T`! /// /// 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 -/// as a discriminant -- `Option>` has the same size as `Shared`. +/// as a discriminant -- `Option>` has the same size as `NonNull`. /// However the pointer may still dangle if it isn't dereferenced. /// -/// Unlike `*mut T`, `Shared` is covariant over `T`. If this is incorrect +/// Unlike `*mut T`, `NonNull` is covariant over `T`. If this is incorrect /// for your use case, you should include some PhantomData in your type to /// provide invariance, such as `PhantomData>` or `PhantomData<&'a mut T>`. /// 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 /// provide a public API that follows the normal shared XOR mutable rules of Rust. -#[allow(missing_debug_implementations)] -#[unstable(feature = "shared", reason = "needs an RFC to flesh out design", - issue = "27730")] -pub struct Shared { +#[stable(feature = "nonnull", since = "1.24.0")] +pub struct NonNull { pointer: NonZero<*const T>, } -/// `Shared` pointers are not `Send` because the data they reference may be aliased. +#[stable(feature = "nonnull", since = "1.24.0")] +impl fmt::Debug for NonNull { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&self.as_ptr(), f) + } +} + +/// `NonNull` pointers are not `Send` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. -#[unstable(feature = "shared", issue = "27730")] -impl !Send for Shared { } +#[stable(feature = "nonnull", since = "1.24.0")] +impl !Send for NonNull { } -/// `Shared` pointers are not `Sync` because the data they reference may be aliased. +/// `NonNull` pointers are not `Sync` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. -#[unstable(feature = "shared", issue = "27730")] -impl !Sync for Shared { } +#[stable(feature = "nonnull", since = "1.24.0")] +impl !Sync for NonNull { } -#[unstable(feature = "shared", issue = "27730")] -impl Shared { - /// Creates a new `Shared` that is dangling, but well-aligned. +impl NonNull { + /// Creates a new `NonNull` that is dangling, but well-aligned. /// /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does. - pub fn empty() -> Self { + #[stable(feature = "nonnull", since = "1.24.0")] + pub fn dangling() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; - Shared::new_unchecked(ptr) + NonNull::new_unchecked(ptr) } } } -#[unstable(feature = "shared", issue = "27730")] -impl Shared { - /// Creates a new `Shared`. +impl NonNull { + /// Creates a new `NonNull`. /// /// # Safety /// /// `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 { - 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 { - 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. + #[stable(feature = "nonnull", since = "1.24.0")] pub fn as_ptr(self) -> *mut T { self.pointer.get() as *mut T } @@ -2520,7 +2545,8 @@ impl Shared { /// /// 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 - /// (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 { &*self.as_ptr() } @@ -2529,56 +2555,50 @@ impl Shared { /// /// 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 - /// (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 { &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")] -impl Clone for Shared { +#[stable(feature = "nonnull", since = "1.24.0")] +impl Clone for NonNull { fn clone(&self) -> Self { *self } } -#[unstable(feature = "shared", issue = "27730")] -impl Copy for Shared { } +#[stable(feature = "nonnull", since = "1.24.0")] +impl Copy for NonNull { } -#[unstable(feature = "shared", issue = "27730")] -impl CoerceUnsized> for Shared where T: Unsize { } +#[stable(feature = "nonnull", since = "1.24.0")] +impl CoerceUnsized> for NonNull where T: Unsize { } -#[unstable(feature = "shared", issue = "27730")] -impl fmt::Pointer for Shared { +#[stable(feature = "nonnull", since = "1.24.0")] +impl fmt::Pointer for NonNull { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } -#[unstable(feature = "shared", issue = "27730")] -impl From> for Shared { +#[stable(feature = "nonnull", since = "1.24.0")] +impl From> for NonNull { fn from(unique: Unique) -> Self { - Shared { pointer: unique.pointer } + NonNull { pointer: unique.pointer } } } -#[unstable(feature = "shared", issue = "27730")] -impl<'a, T: ?Sized> From<&'a mut T> for Shared { +#[stable(feature = "nonnull", since = "1.24.0")] +impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { - Shared { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero::from(reference) } } } -#[unstable(feature = "shared", issue = "27730")] -impl<'a, T: ?Sized> From<&'a T> for Shared { +#[stable(feature = "nonnull", since = "1.24.0")] +impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { - Shared { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero::from(reference) } } } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 2c0009569d75d..1c32452f84635 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -41,7 +41,6 @@ #![feature(trusted_len)] #![feature(try_from)] #![feature(try_trait)] -#![feature(unique)] #![feature(exact_chunks)] extern crate core; diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 98436f0e1d1cd..00f87336f3c80 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -249,9 +249,9 @@ fn test_set_memory() { } #[test] -fn test_unsized_unique() { +fn test_unsized_nonnull() { 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 zs: &[i32] = &[1, 2, 3]; assert!(ys == zs); diff --git a/src/librustc_data_structures/array_vec.rs b/src/librustc_data_structures/array_vec.rs index 57fc78ef53110..511c407d45a7f 100644 --- a/src/librustc_data_structures/array_vec.rs +++ b/src/librustc_data_structures/array_vec.rs @@ -12,7 +12,7 @@ use std::marker::Unsize; 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::hash::{Hash, Hasher}; use std::slice; @@ -146,7 +146,7 @@ impl ArrayVec { tail_start: end, tail_len: len - end, 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_len: usize, iter: slice::Iter<'a, ManuallyDrop>, - array_vec: Shared>, + array_vec: NonNull>, } impl<'a, A: Array> Iterator for Drain<'a, A> { diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 24048e606df47..a35ef2f7ce7ba 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -21,7 +21,6 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![deny(warnings)] -#![feature(shared)] #![feature(collections_range)] #![feature(nonzero)] #![feature(unboxed_closures)] diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 96f98efe4aaa8..73bd5747c105a 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -16,7 +16,7 @@ use marker; use mem::{align_of, size_of, needs_drop}; use mem; use ops::{Deref, DerefMut}; -use ptr::{self, Unique, Shared}; +use ptr::{self, Unique, NonNull}; use self::BucketState::*; @@ -873,7 +873,7 @@ impl RawTable { elems_left, marker: marker::PhantomData, }, - table: Shared::from(self), + table: NonNull::from(self), marker: marker::PhantomData, } } @@ -1020,7 +1020,7 @@ impl IntoIter { /// Iterator over the entries in a table, clearing the table. pub struct Drain<'a, K: 'a, V: 'a> { - table: Shared>, + table: NonNull>, iter: RawBuckets<'static, K, V>, marker: marker::PhantomData<&'a RawTable>, } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index bb38fc550917f..91cc6d25cce01 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -293,11 +293,11 @@ #![feature(placement_in_syntax)] #![feature(placement_new_protocol)] #![feature(prelude_import)] +#![feature(ptr_internals)] #![feature(rand)] #![feature(raw)] #![feature(repr_align)] #![feature(rustc_attrs)] -#![feature(shared)] #![feature(sip_hash_13)] #![feature(slice_bytes)] #![feature(slice_concat_ext)] @@ -315,7 +315,6 @@ #![feature(try_from)] #![feature(unboxed_closures)] #![feature(unicode)] -#![feature(unique)] #![feature(untagged_unions)] #![feature(unwind_attributes)] #![feature(vec_push_all)] diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 53c2211745c32..560876006d3f3 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -17,7 +17,7 @@ use cell::UnsafeCell; use fmt; use ops::{Deref, DerefMut}; use panicking; -use ptr::{Unique, Shared}; +use ptr::{Unique, NonNull}; use rc::Rc; use sync::{Arc, Mutex, RwLock, atomic}; use thread::Result; @@ -196,10 +196,10 @@ impl<'a, T: RefUnwindSafe + ?Sized> UnwindSafe for &'a T {} impl UnwindSafe for *const T {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl UnwindSafe for *mut T {} -#[unstable(feature = "unique", issue = "27730")] +#[unstable(feature = "ptr_internals", issue = "0")] impl UnwindSafe for Unique {} -#[unstable(feature = "shared", issue = "27730")] -impl UnwindSafe for Shared {} +#[stable(feature = "nonnull", since = "1.24.0")] +impl UnwindSafe for NonNull {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl UnwindSafe for Mutex {} #[stable(feature = "catch_unwind", since = "1.9.0")] diff --git a/src/test/run-pass/allocator-alloc-one.rs b/src/test/run-pass/allocator-alloc-one.rs index 712fa2d600177..eaa5bc9080576 100644 --- a/src/test/run-pass/allocator-alloc-one.rs +++ b/src/test/run-pass/allocator-alloc-one.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(allocator_api, unique)] +#![feature(allocator_api, nonnull)] use std::heap::{Heap, Alloc}; diff --git a/src/test/run-pass/issue-23433.rs b/src/test/run-pass/issue-23433.rs index aa13d6fad47c9..7af732f561deb 100644 --- a/src/test/run-pass/issue-23433.rs +++ b/src/test/run-pass/issue-23433.rs @@ -10,13 +10,11 @@ // Don't fail if we encounter a NonZero<*T> where T is an unsized type -#![feature(unique)] - -use std::ptr::Unique; +use std::ptr::NonNull; fn main() { let mut a = [0u8; 5]; - let b: Option> = Some(Unique::from(&mut a)); + let b: Option> = Some(NonNull::from(&mut a)); match b { Some(_) => println!("Got `Some`"), None => panic!("Unexpected `None`"), diff --git a/src/test/rustdoc-js/from_u.js b/src/test/rustdoc-js/from_u.js index 920620a9aeed5..0296788f7a0f5 100644 --- a/src/test/rustdoc-js/from_u.js +++ b/src/test/rustdoc-js/from_u.js @@ -15,7 +15,6 @@ const EXPECTED = { { 'path': 'std::char', 'name': 'from_u32' }, { 'path': 'std::str', '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::i128', 'name': 'from_unsigned' }, ],