diff options
| author | bors <bors@rust-lang.org> | 2017-07-26 21:08:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-07-26 21:08:38 +0000 |
| commit | 599be0d18f4c6ddf36366d2a5a2ca6dc65886896 (patch) | |
| tree | b45698b672fa56662213f15740197fc32db9252f /src/libcore | |
| parent | d02fb3bcf42c05740a47fdfb0d9e5dd8ec24ff37 (diff) | |
| parent | 959ebd6785b48360ac48e334a18b3abe66beef17 (diff) | |
| download | rust-599be0d18f4c6ddf36366d2a5a2ca6dc65886896.tar.gz rust-599be0d18f4c6ddf36366d2a5a2ca6dc65886896.zip | |
Auto merge of #43487 - Mark-Simulacrum:rollup, r=Mark-Simulacrum
Rollup of 10 pull requests - Successful merges: #42959, #43447, #43455, #43456, #43458, #43462, #43463, #43465, #43471, #43480 - Failed merges:
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/nonzero.rs | 89 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 25 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 62 | ||||
| -rw-r--r-- | src/libcore/tests/nonzero.rs | 6 | ||||
| -rw-r--r-- | src/libcore/tests/num/mod.rs | 20 | ||||
| -rw-r--r-- | src/libcore/tests/ptr.rs | 2 |
6 files changed, 160 insertions, 44 deletions
diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 977438051d9..3ff1068b937 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -16,22 +16,48 @@ use ops::CoerceUnsized; /// Unsafe trait to indicate what types are usable with the NonZero struct -pub unsafe trait Zeroable {} - -unsafe impl<T:?Sized> Zeroable for *const T {} -unsafe impl<T:?Sized> Zeroable for *mut T {} -unsafe impl Zeroable for isize {} -unsafe impl Zeroable for usize {} -unsafe impl Zeroable for i8 {} -unsafe impl Zeroable for u8 {} -unsafe impl Zeroable for i16 {} -unsafe impl Zeroable for u16 {} -unsafe impl Zeroable for i32 {} -unsafe impl Zeroable for u32 {} -unsafe impl Zeroable for i64 {} -unsafe impl Zeroable for u64 {} -unsafe impl Zeroable for i128 {} -unsafe impl Zeroable for u128 {} +pub unsafe trait Zeroable { + /// Whether this value is zero + fn is_zero(&self) -> bool; +} + +macro_rules! impl_zeroable_for_pointer_types { + ( $( $Ptr: ty )+ ) => { + $( + /// For fat pointers to be considered "zero", only the "data" part needs to be null. + unsafe impl<T: ?Sized> Zeroable for $Ptr { + #[inline] + fn is_zero(&self) -> bool { + // Cast because `is_null` is only available on thin pointers + (*self as *mut u8).is_null() + } + } + )+ + } +} + +macro_rules! impl_zeroable_for_integer_types { + ( $( $Int: ty )+ ) => { + $( + unsafe impl Zeroable for $Int { + #[inline] + fn is_zero(&self) -> bool { + *self == 0 + } + } + )+ + } +} + +impl_zeroable_for_pointer_types! { + *const T + *mut T +} + +impl_zeroable_for_integer_types! { + usize u8 u16 u32 u64 u128 + isize i8 i16 i32 i64 i128 +} /// A wrapper type for raw pointers and integers that will never be /// NULL or 0 that might allow certain optimizations. @@ -43,10 +69,20 @@ 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". #[inline] - pub const unsafe fn new(inner: T) -> NonZero<T> { + pub const unsafe fn new_unchecked(inner: T) -> Self { NonZero(inner) } + /// Creates an instance of NonZero with the provided value. + #[inline] + pub fn new(inner: T) -> Option<Self> { + if inner.is_zero() { + None + } else { + Some(NonZero(inner)) + } + } + /// Gets the inner value. pub fn get(self) -> T { self.0 @@ -54,3 +90,22 @@ impl<T: Zeroable> NonZero<T> { } impl<T: Zeroable+CoerceUnsized<U>, U: Zeroable> CoerceUnsized<NonZero<U>> for NonZero<T> {} + +impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*mut T> { + fn from(reference: &'a mut T) -> Self { + NonZero(reference) + } +} + +impl<'a, T: ?Sized> From<&'a mut T> for NonZero<*const T> { + fn from(reference: &'a mut T) -> Self { + let ptr: *mut T = reference; + NonZero(ptr) + } +} + +impl<'a, T: ?Sized> From<&'a T> for NonZero<*const T> { + fn from(reference: &'a T) -> Self { + NonZero(reference) + } +} diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 185034a5313..d533310625e 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -2622,8 +2622,11 @@ try_from_both_bounded!(i32, u16, u8); try_from_both_bounded!(i64, u32, u16, u8); try_from_both_bounded!(i128, u64, u32, u16, u8); -#[unstable(feature = "try_from", issue = "33417")] -pub use self::ptr_try_from_impls::*; +// usize/isize +try_from_unbounded!(usize, usize); +try_from_upper_bounded!(usize, isize); +try_from_lower_bounded!(isize, usize); +try_from_unbounded!(isize, isize); #[cfg(target_pointer_width = "16")] mod ptr_try_from_impls { @@ -2631,12 +2634,12 @@ mod ptr_try_from_impls { use convert::TryFrom; try_from_upper_bounded!(usize, u8); - try_from_unbounded!(usize, usize, u16, u32, u64, u128); - try_from_upper_bounded!(usize, i8, i16, isize); + try_from_unbounded!(usize, u16, u32, u64, u128); + try_from_upper_bounded!(usize, i8, i16); try_from_unbounded!(usize, i32, i64, i128); try_from_both_bounded!(isize, u8); - try_from_lower_bounded!(isize, usize, u16, u32, u64, u128); + try_from_lower_bounded!(isize, u16, u32, u64, u128); try_from_both_bounded!(isize, i8); try_from_unbounded!(isize, i16, i32, i64, i128); @@ -2657,12 +2660,12 @@ mod ptr_try_from_impls { use convert::TryFrom; try_from_upper_bounded!(usize, u8, u16); - try_from_unbounded!(usize, usize, u32, u64, u128); - try_from_upper_bounded!(usize, i8, i16, i32, isize); + try_from_unbounded!(usize, u32, u64, u128); + try_from_upper_bounded!(usize, i8, i16, i32); try_from_unbounded!(usize, i64, i128); try_from_both_bounded!(isize, u8, u16); - try_from_lower_bounded!(isize, usize, u32, u64, u128); + try_from_lower_bounded!(isize, u32, u64, u128); try_from_both_bounded!(isize, i8, i16); try_from_unbounded!(isize, i32, i64, i128); @@ -2683,12 +2686,12 @@ mod ptr_try_from_impls { use convert::TryFrom; try_from_upper_bounded!(usize, u8, u16, u32); - try_from_unbounded!(usize, usize, u64, u128); - try_from_upper_bounded!(usize, i8, i16, i32, i64, isize); + try_from_unbounded!(usize, u64, u128); + try_from_upper_bounded!(usize, i8, i16, i32, i64); try_from_unbounded!(usize, i128); try_from_both_bounded!(isize, u8, u16, u32); - try_from_lower_bounded!(isize, usize, u64, u128); + try_from_lower_bounded!(isize, u64, u128); try_from_both_bounded!(isize, i8, i16, i32); try_from_unbounded!(isize, i64, i128); diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index b19e07b8578..60cf1a20530 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -16,6 +16,7 @@ #![stable(feature = "rust1", since = "1.0.0")] +use convert::From; use intrinsics; use ops::CoerceUnsized; use fmt; @@ -1098,7 +1099,7 @@ impl<T: Sized> Unique<T> { pub fn empty() -> Self { unsafe { let ptr = mem::align_of::<T>() as *mut T; - Unique::new(ptr) + Unique::new_unchecked(ptr) } } } @@ -1110,8 +1111,13 @@ impl<T: ?Sized> Unique<T> { /// # Safety /// /// `ptr` must be non-null. - pub const unsafe fn new(ptr: *mut T) -> Unique<T> { - Unique { pointer: NonZero::new(ptr), _marker: PhantomData } + pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { + Unique { pointer: NonZero::new_unchecked(ptr), _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 }) } /// Acquires the underlying `*mut` pointer. @@ -1138,14 +1144,14 @@ impl<T: ?Sized> Unique<T> { } } -#[unstable(feature = "shared", issue = "27730")] +#[unstable(feature = "unique", issue = "27730")] impl<T: ?Sized> Clone for Unique<T> { fn clone(&self) -> Self { *self } } -#[unstable(feature = "shared", issue = "27730")] +#[unstable(feature = "unique", issue = "27730")] impl<T: ?Sized> Copy for Unique<T> { } #[unstable(feature = "unique", issue = "27730")] @@ -1158,6 +1164,20 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> { } } +#[unstable(feature = "unique", issue = "27730")] +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 } + } +} + +#[unstable(feature = "unique", issue = "27730")] +impl<'a, T: ?Sized> From<&'a T> for Unique<T> { + fn from(reference: &'a T) -> Self { + Unique { pointer: NonZero::from(reference), _marker: PhantomData } + } +} + /// A wrapper around a raw `*mut T` that indicates that the possessor /// of this wrapper has shared ownership of the referent. Useful for /// building abstractions like `Rc<T>`, `Arc<T>`, or doubly-linked lists, which @@ -1212,7 +1232,7 @@ impl<T: Sized> Shared<T> { pub fn empty() -> Self { unsafe { let ptr = mem::align_of::<T>() as *mut T; - Shared::new(ptr) + Shared::new_unchecked(ptr) } } } @@ -1224,8 +1244,13 @@ impl<T: ?Sized> Shared<T> { /// # Safety /// /// `ptr` must be non-null. - pub unsafe fn new(ptr: *mut T) -> Self { - Shared { pointer: NonZero::new(ptr), _marker: PhantomData } + pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { + Shared { pointer: NonZero::new_unchecked(ptr), _marker: PhantomData } + } + + /// Creates a new `Shared` if `ptr` is non-null. + pub fn new(ptr: *mut T) -> Option<Self> { + NonZero::new(ptr as *const T).map(|nz| Shared { pointer: nz, _marker: PhantomData }) } /// Acquires the underlying `*mut` pointer. @@ -1278,3 +1303,24 @@ impl<T: ?Sized> fmt::Pointer for Shared<T> { fmt::Pointer::fmt(&self.as_ptr(), f) } } + +#[unstable(feature = "shared", issue = "27730")] +impl<T: ?Sized> From<Unique<T>> for Shared<T> { + fn from(unique: Unique<T>) -> Self { + Shared { pointer: unique.pointer, _marker: PhantomData } + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<'a, T: ?Sized> From<&'a mut T> for Shared<T> { + fn from(reference: &'a mut T) -> Self { + Shared { pointer: NonZero::from(reference), _marker: PhantomData } + } +} + +#[unstable(feature = "shared", issue = "27730")] +impl<'a, T: ?Sized> From<&'a T> for Shared<T> { + fn from(reference: &'a T) -> Self { + Shared { pointer: NonZero::from(reference), _marker: PhantomData } + } +} diff --git a/src/libcore/tests/nonzero.rs b/src/libcore/tests/nonzero.rs index 588fffda35f..a795dd57504 100644 --- a/src/libcore/tests/nonzero.rs +++ b/src/libcore/tests/nonzero.rs @@ -16,7 +16,7 @@ use std::mem::size_of; #[test] fn test_create_nonzero_instance() { let _a = unsafe { - NonZero::new(21) + NonZero::new_unchecked(21) }; } @@ -28,14 +28,14 @@ fn test_size_nonzero_in_option() { #[test] fn test_match_on_nonzero_option() { let a = Some(unsafe { - NonZero::new(42) + NonZero::new_unchecked(42) }); match a { Some(val) => assert_eq!(val.get(), 42), None => panic!("unexpected None while matching on Some(NonZero(_))") } - match unsafe { Some(NonZero::new(43)) } { + match unsafe { Some(NonZero::new_unchecked(43)) } { Some(val) => assert_eq!(val.get(), 43), None => panic!("unexpected None while matching on Some(NonZero(_))") } diff --git a/src/libcore/tests/num/mod.rs b/src/libcore/tests/num/mod.rs index 3e872b34e43..046b81e19f7 100644 --- a/src/libcore/tests/num/mod.rs +++ b/src/libcore/tests/num/mod.rs @@ -279,7 +279,7 @@ test_impl_try_from_always_ok! { test_try_u64u64, u64, u64 } test_impl_try_from_always_ok! { test_try_u64u128, u64, u128 } test_impl_try_from_always_ok! { test_try_u64i128, u64, i128 } -test_impl_try_from_always_ok! { test_try_u128, u128, u128 } +test_impl_try_from_always_ok! { test_try_u128u128, u128, u128 } test_impl_try_from_always_ok! { test_try_i8i8, i8, i8 } test_impl_try_from_always_ok! { test_try_i8i16, i8, i16 } @@ -301,8 +301,12 @@ test_impl_try_from_always_ok! { test_try_i64i128, i64, i128 } test_impl_try_from_always_ok! { test_try_i128i128, i128, i128 } +test_impl_try_from_always_ok! { test_try_usizeusize, usize, usize } +test_impl_try_from_always_ok! { test_try_isizeisize, isize, isize } + assume_usize_width! { test_impl_try_from_always_ok! { test_try_u8usize, u8, usize } + test_impl_try_from_always_ok! { test_try_u8isize, u8, isize } test_impl_try_from_always_ok! { test_try_i8isize, i8, isize } test_impl_try_from_always_ok! { test_try_u16usize, u16, usize } @@ -317,19 +321,27 @@ assume_usize_width! { cfg_block!( #[cfg(target_pointer_width = "16")] { - test_impl_try_from_always_ok! { test_try_u16usize, u16, usize } - test_impl_try_from_always_ok! { test_try_i16isize, i16, isize } + test_impl_try_from_always_ok! { test_try_usizeu16, usize, u16 } + test_impl_try_from_always_ok! { test_try_isizei16, isize, i16 } + test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 } + test_impl_try_from_always_ok! { test_try_usizei32, usize, i32 } + test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 } + test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 } } #[cfg(target_pointer_width = "32")] { + test_impl_try_from_always_ok! { test_try_u16isize, u16, isize } test_impl_try_from_always_ok! { test_try_usizeu32, usize, u32 } test_impl_try_from_always_ok! { test_try_isizei32, isize, i32 } test_impl_try_from_always_ok! { test_try_u32usize, u32, usize } test_impl_try_from_always_ok! { test_try_i32isize, i32, isize } + test_impl_try_from_always_ok! { test_try_usizei64, usize, i64 } } #[cfg(target_pointer_width = "64")] { + test_impl_try_from_always_ok! { test_try_u16isize, u16, isize } test_impl_try_from_always_ok! { test_try_u32usize, u32, usize } + test_impl_try_from_always_ok! { test_try_u32isize, u32, isize } test_impl_try_from_always_ok! { test_try_i32isize, i32, isize } test_impl_try_from_always_ok! { test_try_u64usize, u64, usize } test_impl_try_from_always_ok! { test_try_i64isize, i64, isize } @@ -451,8 +463,8 @@ assume_usize_width! { cfg_block!( #[cfg(target_pointer_width = "16")] { + test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16isize, u16, isize } test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u32, isize } - test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32isize, u64, isize } } #[cfg(target_pointer_width = "32")] { diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index e28dc6a6881..c2d53840f8f 100644 --- a/src/libcore/tests/ptr.rs +++ b/src/libcore/tests/ptr.rs @@ -167,7 +167,7 @@ fn test_set_memory() { #[test] fn test_unsized_unique() { let xs: &[i32] = &[1, 2, 3]; - let ptr = unsafe { Unique::new(xs as *const [i32] as *mut [i32]) }; + let ptr = unsafe { Unique::new_unchecked(xs as *const [i32] as *mut [i32]) }; let ys = unsafe { ptr.as_ref() }; let zs: &[i32] = &[1, 2, 3]; assert!(ys == zs); |
