From 3f557947abf99b262aab994e896522c76329d315 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Jan 2018 09:48:23 +0100 Subject: [PATCH 1/4] NonNull ended up landing in 1.25 --- src/libcore/ptr.rs | 36 ++++++++++++++++++------------------ src/libstd/panic.rs | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index fab5832d905..607e4a1a9fa 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2461,7 +2461,7 @@ impl<'a, T: ?Sized> From> for Unique { } /// Previous name of `NonNull`. -#[rustc_deprecated(since = "1.24", reason = "renamed to `NonNull`")] +#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")] #[unstable(feature = "shared", issue = "27730")] pub type Shared = NonNull; @@ -2482,12 +2482,12 @@ pub type Shared = NonNull; /// 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. -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] pub struct NonNull { pointer: NonZero<*const T>, } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Debug for NonNull { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) @@ -2496,12 +2496,12 @@ impl fmt::Debug for NonNull { /// `NonNull` pointers are not `Send` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl !Send for NonNull { } /// `NonNull` pointers are not `Sync` because the data they reference may be aliased. // NB: This impl is unnecessary, but should provide better error messages. -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl !Sync for NonNull { } impl NonNull { @@ -2509,7 +2509,7 @@ impl NonNull { /// /// This is useful for initializing types which lazily allocate, like /// `Vec::new` does. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub fn dangling() -> Self { unsafe { let ptr = mem::align_of::() as *mut T; @@ -2524,19 +2524,19 @@ impl NonNull { /// # Safety /// /// `ptr` must be non-null. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { NonNull { pointer: NonZero::new_unchecked(ptr) } } /// Creates a new `NonNull` if `ptr` is non-null. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub fn new(ptr: *mut T) -> Option { NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz }) } /// Acquires the underlying `*mut` pointer. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub fn as_ptr(self) -> *mut T { self.pointer.get() as *mut T } @@ -2546,7 +2546,7 @@ impl NonNull { /// 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.as_ptr()`. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub unsafe fn as_ref(&self) -> &T { &*self.as_ptr() } @@ -2556,47 +2556,47 @@ impl NonNull { /// 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.as_ptr()`. - #[stable(feature = "nonnull", since = "1.24.0")] + #[stable(feature = "nonnull", since = "1.25.0")] pub unsafe fn as_mut(&mut self) -> &mut T { &mut *self.as_ptr() } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl Clone for NonNull { fn clone(&self) -> Self { *self } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl Copy for NonNull { } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl CoerceUnsized> for NonNull where T: Unsize { } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Pointer for NonNull { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Pointer::fmt(&self.as_ptr(), f) } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl From> for NonNull { fn from(unique: Unique) -> Self { NonNull { pointer: unique.pointer } } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { NonNull { pointer: NonZero::from(reference) } } } -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { NonNull { pointer: NonZero::from(reference) } diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs index 560876006d3..112e1106093 100644 --- a/src/libstd/panic.rs +++ b/src/libstd/panic.rs @@ -198,7 +198,7 @@ impl UnwindSafe for *const T {} impl UnwindSafe for *mut T {} #[unstable(feature = "ptr_internals", issue = "0")] impl UnwindSafe for Unique {} -#[stable(feature = "nonnull", since = "1.24.0")] +#[stable(feature = "nonnull", since = "1.25.0")] impl UnwindSafe for NonNull {} #[stable(feature = "catch_unwind", since = "1.9.0")] impl UnwindSafe for Mutex {} From ad37e3fc01b533994dfb30f703c28ecdbf66fe10 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Jan 2018 09:48:58 +0100 Subject: [PATCH 2/4] =?UTF-8?q?Move=20Debug=20for=C2=A0NonNull=20impl=20cl?= =?UTF-8?q?oser=20to=20other=20trait=20impls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libcore/ptr.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 607e4a1a9fa..c3b7c4f5d22 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2487,13 +2487,6 @@ pub struct NonNull { pointer: NonZero<*const T>, } -#[stable(feature = "nonnull", since = "1.25.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. #[stable(feature = "nonnull", since = "1.25.0")] @@ -2575,6 +2568,13 @@ impl Copy for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] impl CoerceUnsized> for NonNull where T: Unsize { } +#[stable(feature = "nonnull", since = "1.25.0")] +impl fmt::Debug for NonNull { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Pointer::fmt(&self.as_ptr(), f) + } +} + #[stable(feature = "nonnull", since = "1.25.0")] impl fmt::Pointer for NonNull { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { From 6461c9bdd35d6273b88f22fd5e8708eaf8949283 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Jan 2018 09:51:19 +0100 Subject: [PATCH 3/4] Implement Eq, PartialEq, Ord, PartialOrd, and Hash for NonNull<_> --- src/libcore/ptr.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index c3b7c4f5d22..a0d716fb574 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2582,6 +2582,37 @@ impl fmt::Pointer for NonNull { } } +#[stable(feature = "nonnull", since = "1.25.0")] +impl Eq for NonNull {} + +#[stable(feature = "nonnull", since = "1.25.0")] +impl PartialEq for NonNull { + fn eq(&self, other: &Self) -> bool { + self.as_ptr() == other.as_ptr() + } +} + +#[stable(feature = "nonnull", since = "1.25.0")] +impl Ord for NonNull { + fn cmp(&self, other: &Self) -> Ordering { + self.as_ptr().cmp(&other.as_ptr()) + } +} + +#[stable(feature = "nonnull", since = "1.25.0")] +impl PartialOrd for NonNull { + fn partial_cmp(&self, other: &Self) -> Option { + self.as_ptr().partial_cmp(&other.as_ptr()) + } +} + +#[stable(feature = "nonnull", since = "1.25.0")] +impl hash::Hash for NonNull { + fn hash(&self, state: &mut H) { + self.as_ptr().hash(state) + } +} + #[stable(feature = "nonnull", since = "1.25.0")] impl From> for NonNull { fn from(unique: Unique) -> Self { From b8ffc8a3d8c181e958d2ddf4f108f0cd3a108013 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 21 Jan 2018 09:56:33 +0100 Subject: [PATCH 4/4] Add an unstable `cast() -> NonNull` method to `NonNull`. This is less verbose than going through raw pointers to cast with `as`. --- src/libcore/ptr.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index a0d716fb574..3d84e910fe6 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2553,6 +2553,14 @@ impl NonNull { pub unsafe fn as_mut(&mut self) -> &mut T { &mut *self.as_ptr() } + + /// Cast to a pointer of another type + #[unstable(feature = "nonnull_cast", issue = "47653")] + pub fn cast(self) -> NonNull { + unsafe { + NonNull::new_unchecked(self.as_ptr() as *mut U) + } + } } #[stable(feature = "nonnull", since = "1.25.0")]