From f40877feeb17c538a73fe6294d48af123251a8c5 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 10:39:24 +0100 Subject: [PATCH 1/8] Add 12 num::NonZero* types for each primitive integer RFC: https://github.com/rust-lang/rfcs/pull/2307 --- src/libcore/nonzero.rs | 2 +- src/libcore/num/mod.rs | 87 ++++++++++++++++++++++++++++++++++++++++++ src/libstd/lib.rs | 1 + src/libstd/num.rs | 11 ++++++ 4 files changed, 100 insertions(+), 1 deletion(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 2c966eb3b5794..c6a1dab561757 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -62,7 +62,7 @@ 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); +pub struct NonZero(pub(crate) T); impl NonZero { /// Creates an instance of NonZero with the provided value. diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 09ab7060d37db..d3556ef742b53 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -15,9 +15,96 @@ use convert::{Infallible, TryFrom}; use fmt; use intrinsics; +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::>(), size_of::()); + /// ``` + #[$stability] + #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] + pub struct $Ty(NonZero<$Int>); + + 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 { + 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 = "27730")] + 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 = "27730")] + NonZeroU128(u128); NonZeroI128(i128); +} + /// Provides intentionally-wrapped arithmetic on `T`. /// /// Operations like `+` on `u32` values is intended to never overflow, diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 70a1f82c9a159..5c0a83fde102f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -282,6 +282,7 @@ #![feature(macro_vis_matcher)] #![feature(needs_panic_runtime)] #![feature(exhaustive_patterns)] +#![feature(nonzero)] #![feature(num_bits_bytes)] #![feature(old_wrapping)] #![feature(on_unimplemented)] diff --git a/src/libstd/num.rs b/src/libstd/num.rs index a2c133954a327..5e0406ca2202c 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -21,6 +21,17 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError} #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping; +#[unstable(feature = "nonzero", issue = "27730")] +pub use core::num::{ + NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, + NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize, +}; + +// Change this to `#[unstable(feature = "i128", issue = "35118")]` +// if other NonZero* integer types are stabilizied before 128-bit integers +#[unstable(feature = "nonzero", issue = "27730")] +pub use core::num::{NonZeroU128, NonZeroI128}; + #[cfg(test)] use fmt; #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem}; From 2d13ddb6e14322edcd07135a436d0d848d127fb2 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 10:58:48 +0100 Subject: [PATCH 2/8] Use NonNull<_> instead of NonZero<*const _> in btree internals --- src/liballoc/btree/node.rs | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs index c1618043ce66f..464f8f2f4eced 100644 --- a/src/liballoc/btree/node.rs +++ b/src/liballoc/btree/node.rs @@ -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; @@ -149,14 +148,12 @@ impl BoxedNode { } } - unsafe fn from_ptr(ptr: NonZero<*const LeafNode>) -> Self { - BoxedNode { ptr: Unique::new_unchecked(ptr.get() as *mut LeafNode) } + unsafe fn from_ptr(ptr: NonNull>) -> Self { + BoxedNode { ptr: Unique::from(ptr) } } - fn as_ptr(&self) -> NonZero<*const LeafNode> { - unsafe { - NonZero::from(self.ptr.as_ref()) - } + fn as_ptr(&self) -> NonNull> { + NonNull::from(self.ptr) } } @@ -276,7 +273,7 @@ impl Root { /// `NodeRef` could be pointing to either type of node. pub struct NodeRef { height: usize, - node: NonZero<*const LeafNode>, + node: NonNull>, // This is null unless the borrow type is `Mut` root: *const Root, _marker: PhantomData<(BorrowType, Type)> @@ -302,7 +299,7 @@ unsafe impl Send impl NodeRef { fn as_internal(&self) -> &InternalNode { unsafe { - &*(self.node.get() as *const InternalNode) + &*(self.node.as_ptr() as *mut InternalNode) } } } @@ -310,7 +307,7 @@ impl NodeRef { impl<'a, K, V> NodeRef, K, V, marker::Internal> { fn as_internal_mut(&mut self) -> &mut InternalNode { unsafe { - &mut *(self.node.get() as *mut InternalNode) + &mut *(self.node.as_ptr() as *mut InternalNode) } } } @@ -352,7 +349,7 @@ impl NodeRef { fn as_leaf(&self) -> &LeafNode { unsafe { - &*self.node.get() + self.node.as_ref() } } @@ -382,7 +379,8 @@ impl NodeRef { >, Self > { - if let Some(non_zero) = NonZero::new(self.as_leaf().parent as *const LeafNode) { + let parent_as_leaf = self.as_leaf().parent as *const LeafNode; + if let Some(non_zero) = NonNull::new(parent_as_leaf as *mut _) { Ok(Handle { node: NodeRef { height: self.height + 1, @@ -498,7 +496,7 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { fn as_leaf_mut(&mut self) -> &mut LeafNode { unsafe { - &mut *(self.node.get() as *mut LeafNode) + self.node.as_mut() } } @@ -1241,12 +1239,12 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: } Heap.dealloc( - right_node.node.get() as *mut u8, + right_node.node.as_ptr() as *mut u8, Layout::new::>(), ); } else { Heap.dealloc( - right_node.node.get() as *mut u8, + right_node.node.as_ptr() as *mut u8, Layout::new::>(), ); } From 67f46ce1122121849890ad51c35f0eb6ded14b6f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:02:06 +0100 Subject: [PATCH 3/8] Use num::NonZero* instead of NonZero<_> in rustc and tests --- src/libcore/tests/nonzero.rs | 14 ++++----- src/librustc/ty/subst.rs | 6 ++-- .../obligation_forest/node_index.rs | 6 ++-- src/librustc_mir/dataflow/move_paths/mod.rs | 6 ++-- src/test/run-pass/enum-null-pointer-opt.rs | 9 +++--- src/test/run-pass/issue-23433.rs | 2 +- src/test/ui/print_type_sizes/niche-filling.rs | 31 +++++++------------ .../ui/print_type_sizes/niche-filling.stdout | 10 +++--- 8 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index a795dd575043d..9eaf7529dd3cf 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::nonzero::NonZero; +use core::num::NonZeroU32; use core::option::Option; use core::option::Option::{Some, None}; use std::mem::size_of; @@ -16,28 +16,28 @@ use std::mem::size_of; #[test] fn test_create_nonzero_instance() { let _a = unsafe { - NonZero::new_unchecked(21) + NonZeroU32::new_unchecked(21) }; } #[test] fn test_size_nonzero_in_option() { - assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::(), size_of::>()); } #[test] fn test_match_on_nonzero_option() { let a = Some(unsafe { - NonZero::new_unchecked(42) + NonZeroU32::new_unchecked(42) }); match a { Some(val) => assert_eq!(val.get(), 42), - None => panic!("unexpected None while matching on Some(NonZero(_))") + None => panic!("unexpected None while matching on Some(NonZeroU32(_))") } - match unsafe { Some(NonZero::new_unchecked(43)) } { + match unsafe { Some(NonZeroU32::new_unchecked(43)) } { Some(val) => assert_eq!(val.get(), 43), - None => panic!("unexpected None while matching on Some(NonZero(_))") + None => panic!("unexpected None while matching on Some(NonZeroU32(_))") } } diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index a301049fe1c40..e7b58ae1564aa 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -19,11 +19,11 @@ use syntax_pos::{Span, DUMMY_SP}; use rustc_data_structures::accumulate_vec::AccumulateVec; use core::intrinsics; -use core::nonzero::NonZero; use std::fmt; use std::iter; use std::marker::PhantomData; use std::mem; +use std::num::NonZeroUsize; /// An entity in the Rust typesystem, which can be one of /// several kinds (only types and lifetimes for now). @@ -32,7 +32,7 @@ use std::mem; /// indicate the type (`Ty` or `Region`) it points to. #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub struct Kind<'tcx> { - ptr: NonZero, + ptr: NonZeroUsize, marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>)> } @@ -63,7 +63,7 @@ impl<'tcx> UnpackedKind<'tcx> { Kind { ptr: unsafe { - NonZero::new_unchecked(ptr | tag) + NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData } diff --git a/src/librustc_data_structures/obligation_forest/node_index.rs b/src/librustc_data_structures/obligation_forest/node_index.rs index a72cc6b57eade..37512e4bcd57f 100644 --- a/src/librustc_data_structures/obligation_forest/node_index.rs +++ b/src/librustc_data_structures/obligation_forest/node_index.rs @@ -8,18 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::nonzero::NonZero; +use std::num::NonZeroU32; use std::u32; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct NodeIndex { - index: NonZero, + index: NonZeroU32, } impl NodeIndex { pub fn new(value: usize) -> NodeIndex { assert!(value < (u32::MAX as usize)); - NodeIndex { index: NonZero::new((value as u32) + 1).unwrap() } + NodeIndex { index: NonZeroU32::new((value as u32) + 1).unwrap() } } pub fn get(self) -> usize { diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs index 7b6ebc6fba872..9f6cf8c036e19 100644 --- a/src/librustc_mir/dataflow/move_paths/mod.rs +++ b/src/librustc_mir/dataflow/move_paths/mod.rs @@ -29,17 +29,17 @@ mod abs_domain; // (which is likely to yield a subtle off-by-one error). pub(crate) mod indexes { use std::fmt; - use core::nonzero::NonZero; + use std::num::NonZeroUsize; use rustc_data_structures::indexed_vec::Idx; macro_rules! new_index { ($Index:ident, $debug_name:expr) => { #[derive(Copy, Clone, PartialEq, Eq, Hash)] - pub struct $Index(NonZero); + pub struct $Index(NonZeroUsize); impl Idx for $Index { fn new(idx: usize) -> Self { - $Index(NonZero::new(idx + 1).unwrap()) + $Index(NonZeroUsize::new(idx + 1).unwrap()) } fn index(self) -> usize { self.0.get() - 1 diff --git a/src/test/run-pass/enum-null-pointer-opt.rs b/src/test/run-pass/enum-null-pointer-opt.rs index e296aff2782c5..12f17a1575e82 100644 --- a/src/test/run-pass/enum-null-pointer-opt.rs +++ b/src/test/run-pass/enum-null-pointer-opt.rs @@ -10,10 +10,9 @@ #![feature(nonzero, core)] -extern crate core; - -use core::nonzero::NonZero; use std::mem::size_of; +use std::num::NonZeroUsize; +use std::ptr::NonNull; use std::rc::Rc; use std::sync::Arc; @@ -59,8 +58,8 @@ fn main() { assert_eq!(size_of::<[Box; 1]>(), size_of::; 1]>>()); // Should apply to NonZero - assert_eq!(size_of::>(), size_of::>>()); - assert_eq!(size_of::>(), size_of::>>()); + assert_eq!(size_of::(), size_of::>()); + assert_eq!(size_of::>(), size_of::>>()); // Should apply to types that use NonZero internally assert_eq!(size_of::>(), size_of::>>()); diff --git a/src/test/run-pass/issue-23433.rs b/src/test/run-pass/issue-23433.rs index 7af732f561deb..9547b2f08a6bc 100644 --- a/src/test/run-pass/issue-23433.rs +++ b/src/test/run-pass/issue-23433.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Don't fail if we encounter a NonZero<*T> where T is an unsized type +// Don't fail if we encounter a NonNull where T is an unsized type use std::ptr::NonNull; diff --git a/src/test/ui/print_type_sizes/niche-filling.rs b/src/test/ui/print_type_sizes/niche-filling.rs index 7f234e243e926..875883a2cca7f 100644 --- a/src/test/ui/print_type_sizes/niche-filling.rs +++ b/src/test/ui/print_type_sizes/niche-filling.rs @@ -14,7 +14,7 @@ // This file illustrates how niche-filling enums are handled, // modelled after cases like `Option<&u32>`, `Option` and such. // -// It uses NonZero directly, rather than `&_` or `Unique<_>`, because +// It uses NonZeroU32 rather than `&_` or `Unique<_>`, because // the test is not set up to deal with target-dependent pointer width. // // It avoids using u64/i64 because on some targets that is only 4-byte @@ -25,8 +25,7 @@ #![feature(nonzero)] #![allow(dead_code)] -extern crate core; -use core::nonzero::{NonZero, Zeroable}; +use std::num::NonZeroU32; pub enum MyOption { None, Some(T) } @@ -36,7 +35,7 @@ impl Default for MyOption { pub enum EmbeddedDiscr { None, - Record { pre: u8, val: NonZero, post: u16 }, + Record { pre: u8, val: NonZeroU32, post: u16 }, } impl Default for EmbeddedDiscr { @@ -44,32 +43,24 @@ impl Default for EmbeddedDiscr { } #[derive(Default)] -pub struct IndirectNonZero { +pub struct IndirectNonZero { pre: u8, - nested: NestedNonZero, + nested: NestedNonZero, post: u16, } -pub struct NestedNonZero { +pub struct NestedNonZero { pre: u8, - val: NonZero, + val: NonZeroU32, post: u16, } -impl Default for NestedNonZero { +impl Default for NestedNonZero { fn default() -> Self { - NestedNonZero { pre: 0, val: NonZero::new(T::one()).unwrap(), post: 0 } + NestedNonZero { pre: 0, val: NonZeroU32::new(1).unwrap(), post: 0 } } } -pub trait One { - fn one() -> Self; -} - -impl One for u32 { - fn one() -> Self { 1 } -} - pub enum Enum4 { One(A), Two(B), @@ -79,9 +70,9 @@ pub enum Enum4 { #[start] fn start(_: isize, _: *const *const u8) -> isize { - let _x: MyOption> = Default::default(); + let _x: MyOption = Default::default(); let _y: EmbeddedDiscr = Default::default(); - let _z: MyOption> = Default::default(); + let _z: MyOption = Default::default(); let _a: MyOption = Default::default(); let _b: MyOption = Default::default(); let _c: MyOption = Default::default(); diff --git a/src/test/ui/print_type_sizes/niche-filling.stdout b/src/test/ui/print_type_sizes/niche-filling.stdout index 0f53e7722dd51..79f9ef5a231d3 100644 --- a/src/test/ui/print_type_sizes/niche-filling.stdout +++ b/src/test/ui/print_type_sizes/niche-filling.stdout @@ -1,9 +1,9 @@ -print-type-size type: `IndirectNonZero`: 12 bytes, alignment: 4 bytes +print-type-size type: `IndirectNonZero`: 12 bytes, alignment: 4 bytes print-type-size field `.nested`: 8 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size end padding: 1 bytes -print-type-size type: `MyOption>`: 12 bytes, alignment: 4 bytes +print-type-size type: `MyOption`: 12 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 12 bytes print-type-size field `.0`: 12 bytes @@ -14,7 +14,7 @@ print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes print-type-size end padding: 1 bytes -print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes +print-type-size type: `NestedNonZero`: 8 bytes, alignment: 4 bytes print-type-size field `.val`: 4 bytes print-type-size field `.post`: 2 bytes print-type-size field `.pre`: 1 bytes @@ -32,12 +32,14 @@ print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes -print-type-size type: `MyOption>`: 4 bytes, alignment: 4 bytes +print-type-size type: `MyOption`: 4 bytes, alignment: 4 bytes print-type-size variant `None`: 0 bytes print-type-size variant `Some`: 4 bytes print-type-size field `.0`: 4 bytes print-type-size type: `core::nonzero::NonZero`: 4 bytes, alignment: 4 bytes print-type-size field `.0`: 4 bytes +print-type-size type: `std::num::NonZeroU32`: 4 bytes, alignment: 4 bytes +print-type-size field `.0`: 4 bytes print-type-size type: `Enum4<(), (), (), MyOption>`: 2 bytes, alignment: 1 bytes print-type-size variant `One`: 0 bytes print-type-size field `.0`: 0 bytes From 22f7a0295828c0d75b5487d89343e722b406dd5f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:14:35 +0100 Subject: [PATCH 4/8] Deprecate core::nonzero in favor of ptr::NonNull and num::NonZero* --- src/libcore/nonzero.rs | 5 ++++- src/libcore/num/mod.rs | 4 +++- src/libcore/ptr.rs | 11 +++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index c6a1dab561757..59aaef9d66a00 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -10,8 +10,11 @@ //! Exposes the NonZero lang item which provides optimization hints. #![unstable(feature = "nonzero", - reason = "needs an RFC to flesh out the design", + reason = "deprecated", issue = "27730")] +#![rustc_deprecated(reason = "use `std::ptr::NonNull` or `std::num::NonZero*` instead", + since = "1.26.0")] +#![allow(deprecated)] use ops::CoerceUnsized; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index d3556ef742b53..84f6ab9b76498 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -15,7 +15,7 @@ use convert::{Infallible, TryFrom}; use fmt; use intrinsics; -use nonzero::NonZero; +#[allow(deprecated)] use nonzero::NonZero; use ops; use str::FromStr; @@ -46,9 +46,11 @@ macro_rules! nonzero_integers { /// assert_eq!(size_of::>(), size_of::()); /// ``` #[$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. /// diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 6270e5892b3a0..834a2ed09f77a 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -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}; @@ -2285,6 +2285,7 @@ impl PartialOrd for *mut T { #[unstable(feature = "ptr_internals", issue = "0", reason = "use NonNull instead and consider PhantomData \ (if you also use #[may_dangle]), Send, and/or Sync")] +#[allow(deprecated)] pub struct Unique { pointer: NonZero<*const T>, // NOTE: this marker has no consequences for variance, but is necessary @@ -2332,6 +2333,7 @@ impl Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl Unique { /// Creates a new `Unique`. /// @@ -2392,6 +2394,7 @@ impl fmt::Pointer for Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for Unique { fn from(reference: &'a mut T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } @@ -2399,6 +2402,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for Unique { } #[unstable(feature = "ptr_internals", issue = "0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for Unique { fn from(reference: &'a T) -> Self { Unique { pointer: NonZero::from(reference), _marker: PhantomData } @@ -2436,7 +2440,7 @@ pub type Shared = NonNull; /// provide a public API that follows the normal shared XOR mutable rules of Rust. #[stable(feature = "nonnull", since = "1.25.0")] pub struct NonNull { - pointer: NonZero<*const T>, + #[allow(deprecated)] pointer: NonZero<*const T>, } /// `NonNull` pointers are not `Send` because the data they reference may be aliased. @@ -2463,6 +2467,7 @@ impl NonNull { } } +#[allow(deprecated)] impl NonNull { /// Creates a new `NonNull`. /// @@ -2581,6 +2586,7 @@ impl From> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { NonNull { pointer: NonZero::from(reference) } @@ -2588,6 +2594,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull { } #[stable(feature = "nonnull", since = "1.25.0")] +#[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { NonNull { pointer: NonZero::from(reference) } From 6d682c9adc12c5aee1bac37afa15f01b420be8ee Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 11:45:44 +0100 Subject: [PATCH 5/8] Stop using deprecated NonZero APIs These will eventually be removed (though the NonZero lang item will likely stay). --- src/libcore/ptr.rs | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 834a2ed09f77a..4ab0ceb796773 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2341,17 +2341,21 @@ impl Unique { /// /// `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 { - 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. @@ -2397,7 +2401,7 @@ impl fmt::Pointer for Unique { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for Unique { fn from(reference: &'a mut T) -> Self { - Unique { pointer: NonZero::from(reference), _marker: PhantomData } + Unique { pointer: NonZero(reference as _), _marker: PhantomData } } } @@ -2405,7 +2409,7 @@ impl<'a, T: ?Sized> From<&'a mut T> for Unique { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for Unique { fn from(reference: &'a T) -> Self { - Unique { pointer: NonZero::from(reference), _marker: PhantomData } + Unique { pointer: NonZero(reference as _), _marker: PhantomData } } } @@ -2476,19 +2480,23 @@ impl NonNull { /// `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 { - 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. @@ -2589,7 +2597,7 @@ impl From> for NonNull { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a mut T> for NonNull { fn from(reference: &'a mut T) -> Self { - NonNull { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero(reference as _) } } } @@ -2597,6 +2605,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull { #[allow(deprecated)] impl<'a, T: ?Sized> From<&'a T> for NonNull { fn from(reference: &'a T) -> Self { - NonNull { pointer: NonZero::from(reference) } + NonNull { pointer: NonZero(reference as _) } } } From 7cf1f18cb9209156108e3871e11cb5d63f7f1cf1 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 16 Feb 2018 19:28:13 +0100 Subject: [PATCH 6/8] Test NonZero in a const item in a pattern. (This was buggy before https://github.com/rust-lang/rust/pull/46882) --- src/libcore/tests/nonzero.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index 9eaf7529dd3cf..8d39298bac3d1 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -98,3 +98,26 @@ fn test_match_option_string() { None => panic!("unexpected None while matching on Some(String { ... })") } } + +mod atom { + use core::num::NonZeroU32; + + #[derive(PartialEq, Eq)] + pub struct Atom { + index: NonZeroU32, // private + } + pub const FOO_ATOM: Atom = Atom { index: unsafe { NonZeroU32::new_unchecked(7) } }; +} + +macro_rules! atom { + ("foo") => { atom::FOO_ATOM } +} + +#[test] +fn test_match_nonzero_const_pattern() { + match atom!("foo") { + // Using as a pattern is supported by the compiler: + atom!("foo") => {} + _ => panic!("Expected the const item as a pattern to match.") + } +} From 73c053786dde55059932b9ebcd4a40edf89eae15 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Thu, 8 Mar 2018 16:55:51 +0100 Subject: [PATCH 7/8] Remove deprecated unstable ptr::Shared type alias. It has been deprecated for about one release cycle. --- src/libcore/cell.rs | 5 ++--- src/libcore/ptr.rs | 5 ----- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 36618e86968b5..c8ee166fee3e9 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -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 { -//! ptr: Shared> +//! ptr: NonNull> //! } //! //! struct RcBox { diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 4ab0ceb796773..cebd5989e96cd 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2420,11 +2420,6 @@ impl<'a, T: ?Sized> From> for Unique { } } -/// Previous name of `NonNull`. -#[rustc_deprecated(since = "1.25.0", 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 From a23f685296b2edd59acc998411340184b958ec82 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Sun, 18 Mar 2018 16:58:38 +0100 Subject: [PATCH 8/8] num::NonZero* types now have their own tracking issue: #49137 Fixes #27730 --- src/libcore/nonzero.rs | 7 +------ src/libcore/num/mod.rs | 4 ++-- src/libstd/num.rs | 4 ++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 59aaef9d66a00..19836d98844e2 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -9,9 +9,7 @@ // except according to those terms. //! Exposes the NonZero lang item which provides optimization hints. -#![unstable(feature = "nonzero", - reason = "deprecated", - 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)] @@ -70,9 +68,6 @@ pub struct NonZero(pub(crate) T); impl NonZero { /// 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) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 84f6ab9b76498..2ffcb9e95e2d9 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -92,7 +92,7 @@ macro_rules! nonzero_integers { } nonzero_integers! { - #[unstable(feature = "nonzero", issue = "27730")] + #[unstable(feature = "nonzero", issue = "49137")] NonZeroU8(u8); NonZeroI8(i8); NonZeroU16(u16); NonZeroI16(i16); NonZeroU32(u32); NonZeroI32(i32); @@ -103,7 +103,7 @@ nonzero_integers! { 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 = "27730")] + #[unstable(feature = "nonzero", issue = "49137")] NonZeroU128(u128); NonZeroI128(i128); } diff --git a/src/libstd/num.rs b/src/libstd/num.rs index 5e0406ca2202c..0c618370ac212 100644 --- a/src/libstd/num.rs +++ b/src/libstd/num.rs @@ -21,7 +21,7 @@ pub use core::num::{FpCategory, ParseIntError, ParseFloatError, TryFromIntError} #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::Wrapping; -#[unstable(feature = "nonzero", issue = "27730")] +#[unstable(feature = "nonzero", issue = "49137")] pub use core::num::{ NonZeroU8, NonZeroI8, NonZeroU16, NonZeroI16, NonZeroU32, NonZeroI32, NonZeroU64, NonZeroI64, NonZeroUsize, NonZeroIsize, @@ -29,7 +29,7 @@ pub use core::num::{ // Change this to `#[unstable(feature = "i128", issue = "35118")]` // if other NonZero* integer types are stabilizied before 128-bit integers -#[unstable(feature = "nonzero", issue = "27730")] +#[unstable(feature = "nonzero", issue = "49137")] pub use core::num::{NonZeroU128, NonZeroI128}; #[cfg(test)] use fmt;