Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 12 num::NonZero* types for primitive integers, deprecate core::nonzero #48265

Merged
merged 8 commits into from
Mar 23, 2018
30 changes: 14 additions & 16 deletions src/liballoc/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@

use core::marker::PhantomData;
use core::mem;
use core::nonzero::NonZero;
use core::ptr::{self, Unique};
use core::ptr::{self, Unique, NonNull};
use core::slice;

use boxed::Box;
Expand Down Expand Up @@ -149,14 +148,12 @@ impl<K, V> BoxedNode<K, V> {
}
}

unsafe fn from_ptr(ptr: NonZero<*const LeafNode<K, V>>) -> Self {
BoxedNode { ptr: Unique::new_unchecked(ptr.get() as *mut LeafNode<K, V>) }
unsafe fn from_ptr(ptr: NonNull<LeafNode<K, V>>) -> Self {
BoxedNode { ptr: Unique::from(ptr) }
}

fn as_ptr(&self) -> NonZero<*const LeafNode<K, V>> {
unsafe {
NonZero::from(self.ptr.as_ref())
}
fn as_ptr(&self) -> NonNull<LeafNode<K, V>> {
NonNull::from(self.ptr)
}
}

Expand Down Expand Up @@ -276,7 +273,7 @@ impl<K, V> Root<K, V> {
/// `NodeRef` could be pointing to either type of node.
pub struct NodeRef<BorrowType, K, V, Type> {
height: usize,
node: NonZero<*const LeafNode<K, V>>,
node: NonNull<LeafNode<K, V>>,
// This is null unless the borrow type is `Mut`
root: *const Root<K, V>,
_marker: PhantomData<(BorrowType, Type)>
Expand All @@ -302,15 +299,15 @@ unsafe impl<K: Send, V: Send, Type> Send
impl<BorrowType, K, V> NodeRef<BorrowType, K, V, marker::Internal> {
fn as_internal(&self) -> &InternalNode<K, V> {
unsafe {
&*(self.node.get() as *const InternalNode<K, V>)
&*(self.node.as_ptr() as *mut InternalNode<K, V>)
}
}
}

impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
fn as_internal_mut(&mut self) -> &mut InternalNode<K, V> {
unsafe {
&mut *(self.node.get() as *mut InternalNode<K, V>)
&mut *(self.node.as_ptr() as *mut InternalNode<K, V>)
}
}
}
Expand Down Expand Up @@ -352,7 +349,7 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {

fn as_leaf(&self) -> &LeafNode<K, V> {
unsafe {
&*self.node.get()
self.node.as_ref()
}
}

Expand Down Expand Up @@ -382,7 +379,8 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
>,
Self
> {
if let Some(non_zero) = NonZero::new(self.as_leaf().parent as *const LeafNode<K, V>) {
let parent_as_leaf = self.as_leaf().parent as *const LeafNode<K, V>;
if let Some(non_zero) = NonNull::new(parent_as_leaf as *mut _) {
Ok(Handle {
node: NodeRef {
height: self.height + 1,
Expand Down Expand Up @@ -498,7 +496,7 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {

fn as_leaf_mut(&mut self) -> &mut LeafNode<K, V> {
unsafe {
&mut *(self.node.get() as *mut LeafNode<K, V>)
self.node.as_mut()
}
}

Expand Down Expand Up @@ -1241,12 +1239,12 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Internal>, marker::
}

Heap.dealloc(
right_node.node.get() as *mut u8,
right_node.node.as_ptr() as *mut u8,
Layout::new::<InternalNode<K, V>>(),
);
} else {
Heap.dealloc(
right_node.node.get() as *mut u8,
right_node.node.as_ptr() as *mut u8,
Layout::new::<LeafNode<K, V>>(),
);
}
Expand Down
5 changes: 2 additions & 3 deletions src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,12 @@
//!
//! ```
//! #![feature(core_intrinsics)]
//! #![feature(shared)]
//! use std::cell::Cell;
//! use std::ptr::Shared;
//! use std::ptr::NonNull;
//! use std::intrinsics::abort;
//!
//! struct Rc<T: ?Sized> {
//! ptr: Shared<RcBox<T>>
//! ptr: NonNull<RcBox<T>>
//! }
//!
//! struct RcBox<T: ?Sized> {
Expand Down
12 changes: 5 additions & 7 deletions src/libcore/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
// except according to those terms.

//! Exposes the NonZero lang item which provides optimization hints.
#![unstable(feature = "nonzero",
reason = "needs an RFC to flesh out the design",
issue = "27730")]
#![unstable(feature = "nonzero", reason = "deprecated", issue = "49137")]
#![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead",
since = "1.26.0")]
#![allow(deprecated)]

use ops::CoerceUnsized;

Expand Down Expand Up @@ -62,14 +63,11 @@ impl_zeroable_for_integer_types! {
/// NULL or 0 that might allow certain optimizations.
#[lang = "non_zero"]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
pub struct NonZero<T: Zeroable>(T);
pub struct NonZero<T: Zeroable>(pub(crate) T);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason we need to make this pub(crate) instead of using the new_unchecked and get methods?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is in anticipation for later making this module private and reducing it to its bare minimum (the lang item) SimonSapin#1

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah gotcha. I missed that part in the RFC 👍


impl<T: Zeroable> NonZero<T> {
/// Creates an instance of NonZero with the provided value.
/// You must indeed ensure that the value is actually "non-zero".
#[unstable(feature = "nonzero",
reason = "needs an RFC to flesh out the design",
issue = "27730")]
#[inline]
pub const unsafe fn new_unchecked(inner: T) -> Self {
NonZero(inner)
Expand Down
89 changes: 89 additions & 0 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,98 @@
use convert::{Infallible, TryFrom};
use fmt;
use intrinsics;
#[allow(deprecated)] use nonzero::NonZero;
use ops;
use str::FromStr;

macro_rules! impl_nonzero_fmt {
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
$(
#[$stability]
impl fmt::$Trait for $Ty {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.get().fmt(f)
}
}
)+
}
}

macro_rules! nonzero_integers {
( #[$stability: meta] $( $Ty: ident($Int: ty); )+ ) => {
$(
/// An integer that is known not to equal zero.
///
/// This may enable some memory layout optimization such as:
///
/// ```rust
/// # #![feature(nonzero)]
/// use std::mem::size_of;
/// assert_eq!(size_of::<Option<std::num::NonZeroU32>>(), size_of::<u32>());
/// ```
#[$stability]
#[allow(deprecated)]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct $Ty(NonZero<$Int>);

#[allow(deprecated)]
impl $Ty {
/// Create a non-zero without checking the value.
///
/// # Safety
///
/// The value must not be zero.
#[$stability]
#[inline]
pub const unsafe fn new_unchecked(n: $Int) -> Self {
$Ty(NonZero(n))
}

/// Create a non-zero if the given value is not zero.
#[$stability]
#[inline]
pub fn new(n: $Int) -> Option<Self> {
if n != 0 {
Some($Ty(NonZero(n)))
} else {
None
}
}

/// Returns the value as a primitive type.
#[$stability]
#[inline]
pub fn get(self) -> $Int {
self.0 .0
}

}

impl_nonzero_fmt! {
#[$stability]
(Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
}
)+
}
}

nonzero_integers! {
#[unstable(feature = "nonzero", issue = "49137")]
NonZeroU8(u8); NonZeroI8(i8);
NonZeroU16(u16); NonZeroI16(i16);
NonZeroU32(u32); NonZeroI32(i32);
NonZeroU64(u64); NonZeroI64(i64);
NonZeroUsize(usize); NonZeroIsize(isize);
}

nonzero_integers! {
// Change this to `#[unstable(feature = "i128", issue = "35118")]`
// if other NonZero* integer types are stabilizied before 128-bit integers
#[unstable(feature = "nonzero", issue = "49137")]
NonZeroU128(u128); NonZeroI128(i128);
}

/// Provides intentionally-wrapped arithmetic on `T`.
///
/// Operations like `+` on `u32` values is intended to never overflow,
Expand Down
44 changes: 27 additions & 17 deletions src/libcore/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use fmt;
use hash;
use marker::{PhantomData, Unsize};
use mem;
use nonzero::NonZero;
#[allow(deprecated)] use nonzero::NonZero;

use cmp::Ordering::{self, Less, Equal, Greater};

Expand Down Expand Up @@ -2285,6 +2285,7 @@ impl<T: ?Sized> PartialOrd for *mut T {
#[unstable(feature = "ptr_internals", issue = "0",
reason = "use NonNull instead and consider PhantomData<T> \
(if you also use #[may_dangle]), Send, and/or Sync")]
#[allow(deprecated)]
pub struct Unique<T: ?Sized> {
pointer: NonZero<*const T>,
// NOTE: this marker has no consequences for variance, but is necessary
Expand Down Expand Up @@ -2332,24 +2333,29 @@ impl<T: Sized> Unique<T> {
}

#[unstable(feature = "ptr_internals", issue = "0")]
#[allow(deprecated)]
impl<T: ?Sized> Unique<T> {
/// Creates a new `Unique`.
///
/// # Safety
///
/// `ptr` must be non-null.
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
Unique { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData }
Unique { pointer: NonZero(ptr as _), _marker: PhantomData }
}

/// Creates a new `Unique` if `ptr` is non-null.
pub fn new(ptr: *mut T) -> Option<Self> {
NonZero::new(ptr as *const T).map(|nz| Unique { pointer: nz, _marker: PhantomData })
if !ptr.is_null() {
Some(Unique { pointer: NonZero(ptr as _), _marker: PhantomData })
} else {
None
}
}

/// Acquires the underlying `*mut` pointer.
pub fn as_ptr(self) -> *mut T {
self.pointer.get() as *mut T
self.pointer.0 as *mut T
}

/// Dereferences the content.
Expand Down Expand Up @@ -2392,16 +2398,18 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
}

#[unstable(feature = "ptr_internals", issue = "0")]
#[allow(deprecated)]
impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> {
fn from(reference: &'a mut T) -> Self {
Unique { pointer: NonZero::from(reference), _marker: PhantomData }
Unique { pointer: NonZero(reference as _), _marker: PhantomData }
}
}

#[unstable(feature = "ptr_internals", issue = "0")]
#[allow(deprecated)]
impl<'a, T: ?Sized> From<&'a T> for Unique<T> {
fn from(reference: &'a T) -> Self {
Unique { pointer: NonZero::from(reference), _marker: PhantomData }
Unique { pointer: NonZero(reference as _), _marker: PhantomData }
}
}

Expand All @@ -2412,11 +2420,6 @@ impl<'a, T: ?Sized> From<NonNull<T>> for Unique<T> {
}
}

/// Previous name of `NonNull`.
#[rustc_deprecated(since = "1.25.0", reason = "renamed to `NonNull`")]
#[unstable(feature = "shared", issue = "27730")]
pub type Shared<T> = NonNull<T>;

/// `*mut T` but non-zero and covariant.
///
/// This is often the correct thing to use when building data structures using
Expand All @@ -2436,7 +2439,7 @@ pub type Shared<T> = NonNull<T>;
/// provide a public API that follows the normal shared XOR mutable rules of Rust.
#[stable(feature = "nonnull", since = "1.25.0")]
pub struct NonNull<T: ?Sized> {
pointer: NonZero<*const T>,
#[allow(deprecated)] pointer: NonZero<*const T>,
}

/// `NonNull` pointers are not `Send` because the data they reference may be aliased.
Expand All @@ -2463,6 +2466,7 @@ impl<T: Sized> NonNull<T> {
}
}

#[allow(deprecated)]
impl<T: ?Sized> NonNull<T> {
/// Creates a new `NonNull`.
///
Expand All @@ -2471,19 +2475,23 @@ impl<T: ?Sized> NonNull<T> {
/// `ptr` must be non-null.
#[stable(feature = "nonnull", since = "1.25.0")]
pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
NonNull { pointer: NonZero::new_unchecked(ptr) }
NonNull { pointer: NonZero(ptr as _) }
}

/// Creates a new `NonNull` if `ptr` is non-null.
#[stable(feature = "nonnull", since = "1.25.0")]
pub fn new(ptr: *mut T) -> Option<Self> {
NonZero::new(ptr as *const T).map(|nz| NonNull { pointer: nz })
if !ptr.is_null() {
Some(NonNull { pointer: NonZero(ptr as _) })
} else {
None
}
}

/// Acquires the underlying `*mut` pointer.
#[stable(feature = "nonnull", since = "1.25.0")]
pub fn as_ptr(self) -> *mut T {
self.pointer.get() as *mut T
self.pointer.0 as *mut T
}

/// Dereferences the content.
Expand Down Expand Up @@ -2581,15 +2589,17 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
}

#[stable(feature = "nonnull", since = "1.25.0")]
#[allow(deprecated)]
impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> {
fn from(reference: &'a mut T) -> Self {
NonNull { pointer: NonZero::from(reference) }
NonNull { pointer: NonZero(reference as _) }
}
}

#[stable(feature = "nonnull", since = "1.25.0")]
#[allow(deprecated)]
impl<'a, T: ?Sized> From<&'a T> for NonNull<T> {
fn from(reference: &'a T) -> Self {
NonNull { pointer: NonZero::from(reference) }
NonNull { pointer: NonZero(reference as _) }
}
}
Loading