about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-12-06 10:18:17 +0000
committerbors <bors@rust-lang.org>2018-12-06 10:18:17 +0000
commit128a1fa4e1f85e04f522653bb9bee83ed6523440 (patch)
treecf1bb66e041bed563653ac45ea58bfa863d7518a /src/libcore
parent77a6a61f066af3dd693d8527a8a1bf5a446d295c (diff)
parentcb71752f911c47426e208a9f5f1862d4c0e56aa4 (diff)
downloadrust-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.rs2
-rw-r--r--src/libcore/nonzero.rs17
-rw-r--r--src/libcore/num/mod.rs4
-rw-r--r--src/libcore/ptr.rs14
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 _) } }
     }
 }