//! Free functions to create `&[T]` and `&mut [T]`.
use crate::array;
-use crate::intrinsics::is_aligned_and_not_null;
-use crate::mem;
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")]
-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"
- );
+#[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);
+
// 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")]
-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"
- );
+#[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);
+
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
}
+// 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) {}
+
/// 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")]