1
Fork 0

Stabilize std::ptr::NonNull

This commit is contained in:
Simon Sapin 2017-12-22 19:50:21 +01:00
parent 2d51e74580
commit 55c50cd8ac
8 changed files with 20 additions and 30 deletions

View file

@ -288,16 +288,13 @@ impl<T: ?Sized> Box<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(nonnull)]
///
/// fn main() { /// fn main() {
/// let x = Box::new(5); /// let x = Box::new(5);
/// let ptr = Box::into_nonnull_raw(x); /// let ptr = Box::into_nonnull_raw(x);
/// let x = unsafe { Box::from_nonnull_raw(ptr) }; /// let x = unsafe { Box::from_nonnull_raw(ptr) };
/// } /// }
/// ``` /// ```
#[unstable(feature = "nonnull", reason = "needs an RFC to flesh out design", #[stable(feature = "nonnull", since = "1.24.0")]
issue = "27730")]
#[inline] #[inline]
pub unsafe fn from_nonnull_raw(u: NonNull<T>) -> Self { pub unsafe fn from_nonnull_raw(u: NonNull<T>) -> Self {
Box(u.into()) Box(u.into())
@ -352,15 +349,12 @@ impl<T: ?Sized> Box<T> {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// #![feature(nonnull)]
///
/// fn main() { /// fn main() {
/// let x = Box::new(5); /// let x = Box::new(5);
/// let ptr = Box::into_nonnull_raw(x); /// let ptr = Box::into_nonnull_raw(x);
/// } /// }
/// ``` /// ```
#[unstable(feature = "nonnull", reason = "needs an RFC to flesh out design", #[stable(feature = "nonnull", since = "1.24.0")]
issue = "27730")]
#[inline] #[inline]
pub fn into_nonnull_raw(b: Box<T>) -> NonNull<T> { pub fn into_nonnull_raw(b: Box<T>) -> NonNull<T> {
Box::into_unique(b).into() Box::into_unique(b).into()

View file

@ -103,7 +103,6 @@
#![feature(iter_rfold)] #![feature(iter_rfold)]
#![feature(lang_items)] #![feature(lang_items)]
#![feature(needs_allocator)] #![feature(needs_allocator)]
#![feature(nonnull)]
#![feature(nonzero)] #![feature(nonzero)]
#![feature(offset_to)] #![feature(offset_to)]
#![feature(optin_builtin_traits)] #![feature(optin_builtin_traits)]

View file

@ -2481,13 +2481,12 @@ pub type Shared<T> = NonNull<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.
#[unstable(feature = "shared", reason = "needs an RFC to flesh out design", #[stable(feature = "nonnull", since = "1.24.0")]
issue = "27730")]
pub struct NonNull<T: ?Sized> { pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>, pointer: NonZero<*const T>,
} }
#[unstable(feature = "shared", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> fmt::Debug for NonNull<T> { impl<T: ?Sized> fmt::Debug for NonNull<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:p}", self.as_ptr()) write!(f, "{:p}", self.as_ptr())
@ -2496,20 +2495,20 @@ impl<T: ?Sized> fmt::Debug for NonNull<T> {
/// `NonNull` pointers are not `Send` 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 = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> !Send for NonNull<T> { } impl<T: ?Sized> !Send for NonNull<T> { }
/// `NonNull` 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. // NB: This impl is unnecessary, but should provide better error messages.
#[unstable(feature = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> !Sync for NonNull<T> { } impl<T: ?Sized> !Sync for NonNull<T> { }
#[unstable(feature = "nonnull", issue = "27730")]
impl<T: Sized> NonNull<T> { impl<T: Sized> NonNull<T> {
/// Creates a new `NonNull` that is dangling, but well-aligned. /// 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.
#[stable(feature = "nonnull", since = "1.24.0")]
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;
@ -2518,24 +2517,25 @@ impl<T: Sized> NonNull<T> {
} }
} }
#[unstable(feature = "nonnull", issue = "27730")]
impl<T: ?Sized> NonNull<T> { impl<T: ?Sized> NonNull<T> {
/// Creates a new `NonNull`. /// Creates a new `NonNull`.
/// ///
/// # Safety /// # Safety
/// ///
/// `ptr` must be non-null. /// `ptr` must be non-null.
#[unstable(feature = "nonnull", 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 {
NonNull { pointer: NonZero::new_unchecked(ptr) } NonNull { pointer: NonZero::new_unchecked(ptr) }
} }
/// Creates a new `NonNull` 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| NonNull { 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
} }
@ -2545,6 +2545,7 @@ impl<T: ?Sized> NonNull<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.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()
} }
@ -2554,46 +2555,47 @@ impl<T: ?Sized> NonNull<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.ptr_mut()`.
#[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()
} }
} }
#[unstable(feature = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> Clone for NonNull<T> { impl<T: ?Sized> Clone for NonNull<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
*self *self
} }
} }
#[unstable(feature = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> Copy for NonNull<T> { } impl<T: ?Sized> Copy for NonNull<T> { }
#[unstable(feature = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { } impl<T: ?Sized, U: ?Sized> CoerceUnsized<NonNull<U>> for NonNull<T> where T: Unsize<U> { }
#[unstable(feature = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> fmt::Pointer for NonNull<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 = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: ?Sized> From<Unique<T>> for NonNull<T> { impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
fn from(unique: Unique<T>) -> Self { fn from(unique: Unique<T>) -> Self {
NonNull { pointer: unique.pointer } NonNull { pointer: unique.pointer }
} }
} }
#[unstable(feature = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<'a, T: ?Sized> From<&'a mut T> for NonNull<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 {
NonNull { pointer: NonZero::from(reference) } NonNull { pointer: NonZero::from(reference) }
} }
} }
#[unstable(feature = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<'a, T: ?Sized> From<&'a T> for NonNull<T> { impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
fn from(reference: &'a T) -> Self { fn from(reference: &'a T) -> Self {
NonNull { pointer: NonZero::from(reference) } NonNull { pointer: NonZero::from(reference) }

View file

@ -27,7 +27,6 @@
#![feature(iterator_try_fold)] #![feature(iterator_try_fold)]
#![feature(iter_rfind)] #![feature(iter_rfind)]
#![feature(iter_rfold)] #![feature(iter_rfold)]
#![feature(nonnull)]
#![feature(nonzero)] #![feature(nonzero)]
#![feature(pattern)] #![feature(pattern)]
#![feature(raw)] #![feature(raw)]

View file

@ -22,7 +22,6 @@
#![deny(warnings)] #![deny(warnings)]
#![feature(collections_range)] #![feature(collections_range)]
#![feature(nonnull)]
#![feature(nonzero)] #![feature(nonzero)]
#![feature(unboxed_closures)] #![feature(unboxed_closures)]
#![feature(fn_traits)] #![feature(fn_traits)]

View file

@ -283,7 +283,6 @@
#![feature(macro_vis_matcher)] #![feature(macro_vis_matcher)]
#![feature(needs_panic_runtime)] #![feature(needs_panic_runtime)]
#![feature(never_type)] #![feature(never_type)]
#![feature(nonnull)]
#![feature(num_bits_bytes)] #![feature(num_bits_bytes)]
#![feature(old_wrapping)] #![feature(old_wrapping)]
#![feature(on_unimplemented)] #![feature(on_unimplemented)]

View file

@ -198,7 +198,7 @@ impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {} impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
#[unstable(feature = "ptr_internals", issue = "0")] #[unstable(feature = "ptr_internals", issue = "0")]
impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {} impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
#[unstable(feature = "nonnull", issue = "27730")] #[stable(feature = "nonnull", since = "1.24.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<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> {}

View file

@ -10,8 +10,6 @@
// 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(nonnull)]
use std::ptr::NonNull; use std::ptr::NonNull;
fn main() { fn main() {