Change:
Currently,  is not , since it uses with a non- check: can't be made , since it involves ptr-int cast to check the alignment: Recently intrinsic , it allows to run different code in CTFE and runtime. This, in turn, allows us to only make the alignment check in runtime and ignore it in the CTFE where it doesn't make much sense. See also: cc and (it seems like use of requires approval of all of the above teams) label +T-lang +T-libs +A-const-eval +A-const-fn
Another approach to make const would be to disable the checks altogether, but since we already have , that seems unreasonable.
cc opinions before we escalate to lang and libs?
If a new intrinsic was in the spirit of and , this could possibly provide a solution without . Something like:
It seems useless to be able to perform any align checks in constants. The CTFE catches invalid pointer dereferences anyways.
Yes, but we also want to catch invalid pointer dereferences when we are not in CTFE, hence the idea of the function/intrinsic.
So why not use ?
It doesn't catch insufficiently aligned pointers though.

Discussion:
#![feature(const_caller_location)] #![feature(const_cell_into_inner)] #![feature(const_discriminant)] <ins> #![cfg_attr(not(bootstrap), feature(const_eval_select))] </ins> #![feature(const_float_bits_conv)] #![feature(const_float_classify)] #![feature(const_fmt_arguments_new)]

//! Free functions to create `&[T]` and `&mut [T]`. use crate::array; <del> use crate::intrinsics::is_aligned_and_not_null; use crate::mem; </del> use crate::ptr; /// Forms a slice from a pointer and a length.

/// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] #[stable(feature = "rust1", since = "1.0.0")] <del> pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); debug_assert!( mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering at least half the address space" ); </del> <ins> #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { debug_check_data_len(data, len); </ins> // SAFETY: the caller must uphold the safety contract for `from_raw_parts`. unsafe { &*ptr::slice_from_raw_parts(data, len) } }

/// [`NonNull::dangling()`]: ptr::NonNull::dangling #[inline] #[stable(feature = "rust1", since = "1.0.0")] <del> pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); debug_assert!( mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering at least half the address space" ); </del> <ins> #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { debug_check_data_len(data as _, len); </ins> // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`. unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) } } <ins> // In debug builds checks that `data` pointer is aligned and non-null and that slice with given `len` would cover less than half the address space #[cfg(all(not(bootstrap), debug_assertions))] #[unstable(feature = "const_slice_from_raw_parts", issue = "67456")] #[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] const fn debug_check_data_len<T>(data: *const T, len: usize) { fn rt_check<T>(data: *const T) { use crate::intrinsics::is_aligned_and_not_null; assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); } const fn noop<T>(_: *const T) {} // SAFETY: // // `rt_check` is just a debug assert to hint users that they are causing UB, // it is not required for safety (the safety must be guatanteed by // the `from_raw_parts[_mut]` caller). // // Since the checks are not required, we ignore them in CTFE as they can't // be done there (alignment does not make much sense there). unsafe { crate::intrinsics::const_eval_select((data,), noop, rt_check); } assert!( crate::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize, "attempt to create slice covering at least half the address space" ); } #[cfg(not(all(not(bootstrap), debug_assertions)))] const fn debug_check_data_len<T>(_data: *const T, _len: usize) {} </ins> /// Converts a reference to T into a slice of length 1 (without copying). #[stable(feature = "from_ref", since = "1.28.0")] #[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")]