Skip to content

Commit

Permalink
Rollup merge of rust-lang#48265 - SimonSapin:nonzero, r=KodrAus
Browse files Browse the repository at this point in the history
Add 12 num::NonZero* types for primitive integers, deprecate core::nonzero

RFC: rust-lang/rfcs#2307
Tracking issue: ~~rust-lang#27730 rust-lang#49137
Fixes rust-lang#27730
  • Loading branch information
frewsxcv authored Mar 23, 2018
2 parents 52f7e88 + a23f685 commit a803046
Show file tree
Hide file tree
Showing 15 changed files with 210 additions and 89 deletions.
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);

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::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

0 comments on commit a803046

Please sign in to comment.