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:
commit
128a1fa4e1
38 changed files with 868 additions and 137 deletions
|
|
@ -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> {}
|
||||
|
|
|
|||
|
|
@ -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> {}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 _) } }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue