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
This commit is contained in:
bors 2018-12-06 10:18:17 +00:00
commit 128a1fa4e1
38 changed files with 868 additions and 137 deletions

View file

@ -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> {}

View file

@ -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> {}

View file

@ -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
}

View file

@ -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 _) } }
}
}