diff options
| author | bors <bors@rust-lang.org> | 2018-12-06 10:18:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-12-06 10:18:17 +0000 |
| commit | 128a1fa4e1f85e04f522653bb9bee83ed6523440 (patch) | |
| tree | cf1bb66e041bed563653ac45ea58bfa863d7518a /src/libcore | |
| parent | 77a6a61f066af3dd693d8527a8a1bf5a446d295c (diff) | |
| parent | cb71752f911c47426e208a9f5f1862d4c0e56aa4 (diff) | |
| download | rust-128a1fa4e1f85e04f522653bb9bee83ed6523440.tar.gz rust-128a1fa4e1f85e04f522653bb9bee83ed6523440.zip | |
Auto merge of #55635 - oli-obk:min_const_unsafe_fn, r=nikomatsakis
Allow calling `const unsafe fn` in `const fn` behind a feature gate cc #55607 r? @Centril
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/marker.rs | 2 | ||||
| -rw-r--r-- | src/libcore/nonzero.rs | 17 | ||||
| -rw-r--r-- | src/libcore/num/mod.rs | 4 | ||||
| -rw-r--r-- | src/libcore/ptr.rs | 14 |
4 files changed, 23 insertions, 14 deletions
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs index 3bcdfabbb24..23f07773f3f 100644 --- a/src/libcore/marker.rs +++ b/src/libcore/marker.rs @@ -596,7 +596,7 @@ mod impls { /// This affects, for example, whether a `static` of that type is /// placed in read-only static memory or writable static memory. #[lang = "freeze"] -unsafe auto trait Freeze {} +pub(crate) unsafe auto trait Freeze {} impl<T: ?Sized> !Freeze for UnsafeCell<T> {} unsafe impl<T: ?Sized> Freeze for PhantomData<T> {} diff --git a/src/libcore/nonzero.rs b/src/libcore/nonzero.rs index 436cd1fc057..a89c6ca60cb 100644 --- a/src/libcore/nonzero.rs +++ b/src/libcore/nonzero.rs @@ -11,14 +11,23 @@ //! Exposes the NonZero lang item which provides optimization hints. use ops::{CoerceUnsized, DispatchFromDyn}; +use marker::Freeze; /// A wrapper type for raw pointers and integers that will never be /// NULL or 0 that might allow certain optimizations. #[rustc_layout_scalar_valid_range_start(1)] -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Copy, Eq, PartialEq, Ord, PartialOrd, Hash)] #[repr(transparent)] -pub(crate) struct NonZero<T>(pub(crate) T); +pub(crate) struct NonZero<T: Freeze>(pub(crate) T); -impl<T: CoerceUnsized<U>, U> CoerceUnsized<NonZero<U>> for NonZero<T> {} +// Do not call `T::clone` as theoretically it could turn the field into `0` +// invalidating `NonZero`'s invariant. +impl<T: Copy + Freeze> Clone for NonZero<T> { + fn clone(&self) -> Self { + unsafe { NonZero(self.0) } + } +} -impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<NonZero<U>> for NonZero<T> {} +impl<T: CoerceUnsized<U> + Freeze, U: Freeze> CoerceUnsized<NonZero<U>> for NonZero<T> {} + +impl<T: DispatchFromDyn<U> + Freeze, U: Freeze> DispatchFromDyn<NonZero<U>> for NonZero<T> {} diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 805be431328..7f5d596b220 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -70,7 +70,7 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st #[stable(feature = "nonzero", since = "1.28.0")] #[inline] pub const unsafe fn new_unchecked(n: $Int) -> Self { - $Ty(NonZero(n)) + $Ty(unsafe { NonZero(n) }) } /// Create a non-zero if the given value is not zero. @@ -78,7 +78,7 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st #[inline] pub fn new(n: $Int) -> Option<Self> { if n != 0 { - Some($Ty(NonZero(n))) + Some($Ty(unsafe { NonZero(n) })) } else { None } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index d3a74ed2a68..0387708033b 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -2759,7 +2759,7 @@ impl<T: ?Sized> Unique<T> { /// Creates a new `Unique` if `ptr` is non-null. pub fn new(ptr: *mut T) -> Option<Self> { if !ptr.is_null() { - Some(Unique { pointer: NonZero(ptr as _), _marker: PhantomData }) + Some(Unique { pointer: unsafe { NonZero(ptr as _) }, _marker: PhantomData }) } else { None } @@ -2815,14 +2815,14 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> { #[unstable(feature = "ptr_internals", issue = "0")] impl<'a, T: ?Sized> From<&'a mut T> for Unique<T> { fn from(reference: &'a mut T) -> Self { - Unique { pointer: NonZero(reference as _), _marker: PhantomData } + Unique { pointer: unsafe { NonZero(reference as _) }, _marker: PhantomData } } } #[unstable(feature = "ptr_internals", issue = "0")] impl<'a, T: ?Sized> From<&'a T> for Unique<T> { fn from(reference: &'a T) -> Self { - Unique { pointer: NonZero(reference as _), _marker: PhantomData } + Unique { pointer: unsafe { NonZero(reference as _) }, _marker: PhantomData } } } @@ -2895,7 +2895,7 @@ impl<T: ?Sized> NonNull<T> { #[stable(feature = "nonnull", since = "1.25.0")] #[inline] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { - NonNull { pointer: NonZero(ptr as _) } + NonNull { pointer: unsafe { NonZero(ptr as _) } } } /// Creates a new `NonNull` if `ptr` is non-null. @@ -2903,7 +2903,7 @@ impl<T: ?Sized> NonNull<T> { #[inline] pub fn new(ptr: *mut T) -> Option<Self> { if !ptr.is_null() { - Some(NonNull { pointer: NonZero(ptr as _) }) + Some(unsafe { Self::new_unchecked(ptr) }) } else { None } @@ -3025,7 +3025,7 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> { impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> { #[inline] fn from(reference: &'a mut T) -> Self { - NonNull { pointer: NonZero(reference as _) } + NonNull { pointer: unsafe { NonZero(reference as _) } } } } @@ -3033,6 +3033,6 @@ impl<'a, T: ?Sized> From<&'a mut T> for NonNull<T> { impl<'a, T: ?Sized> From<&'a T> for NonNull<T> { #[inline] fn from(reference: &'a T) -> Self { - NonNull { pointer: NonZero(reference as _) } + NonNull { pointer: unsafe { NonZero(reference as _) } } } } |
