|
1 | 1 | //! Free functions to create `&[T]` and `&mut [T]`.
|
2 | 2 |
|
3 | 3 | use crate::array;
|
4 |
| -use crate::intrinsics::is_aligned_and_not_null; |
5 |
| -use crate::mem; |
6 | 4 | use crate::ptr;
|
7 | 5 |
|
8 | 6 | /// Forms a slice from a pointer and a length.
|
@@ -85,12 +83,10 @@ use crate::ptr;
|
85 | 83 | /// [`NonNull::dangling()`]: ptr::NonNull::dangling
|
86 | 84 | #[inline]
|
87 | 85 | #[stable(feature = "rust1", since = "1.0.0")]
|
88 |
| -pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { |
89 |
| - debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); |
90 |
| - debug_assert!( |
91 |
| - mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize, |
92 |
| - "attempt to create slice covering at least half the address space" |
93 |
| - ); |
| 86 | +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] |
| 87 | +pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { |
| 88 | + debug_check_data_len(data, len); |
| 89 | + |
94 | 90 | // SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
|
95 | 91 | unsafe { &*ptr::slice_from_raw_parts(data, len) }
|
96 | 92 | }
|
@@ -126,16 +122,48 @@ pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
|
126 | 122 | /// [`NonNull::dangling()`]: ptr::NonNull::dangling
|
127 | 123 | #[inline]
|
128 | 124 | #[stable(feature = "rust1", since = "1.0.0")]
|
129 |
| -pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { |
130 |
| - debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); |
131 |
| - debug_assert!( |
132 |
| - mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize, |
133 |
| - "attempt to create slice covering at least half the address space" |
134 |
| - ); |
| 125 | +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] |
| 126 | +pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { |
| 127 | + debug_check_data_len(data as _, len); |
| 128 | + |
135 | 129 | // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
|
136 | 130 | unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
|
137 | 131 | }
|
138 | 132 |
|
| 133 | +// 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 |
| 134 | +#[cfg(all(not(bootstrap), debug_assertions))] |
| 135 | +#[unstable(feature = "const_slice_from_raw_parts", issue = "67456")] |
| 136 | +#[rustc_const_unstable(feature = "const_slice_from_raw_parts", issue = "67456")] |
| 137 | +const fn debug_check_data_len<T>(data: *const T, len: usize) { |
| 138 | + fn rt_check<T>(data: *const T) { |
| 139 | + use crate::intrinsics::is_aligned_and_not_null; |
| 140 | + |
| 141 | + assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice"); |
| 142 | + } |
| 143 | + |
| 144 | + const fn noop<T>(_: *const T) {} |
| 145 | + |
| 146 | + // SAFETY: |
| 147 | + // |
| 148 | + // `rt_check` is just a debug assert to hint users that they are causing UB, |
| 149 | + // it is not required for safety (the safety must be guatanteed by |
| 150 | + // the `from_raw_parts[_mut]` caller). |
| 151 | + // |
| 152 | + // Since the checks are not required, we ignore them in CTFE as they can't |
| 153 | + // be done there (alignment does not make much sense there). |
| 154 | + unsafe { |
| 155 | + crate::intrinsics::const_eval_select((data,), noop, rt_check); |
| 156 | + } |
| 157 | + |
| 158 | + assert!( |
| 159 | + crate::mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize, |
| 160 | + "attempt to create slice covering at least half the address space" |
| 161 | + ); |
| 162 | +} |
| 163 | + |
| 164 | +#[cfg(not(all(not(bootstrap), debug_assertions)))] |
| 165 | +const fn debug_check_data_len<T>(_data: *const T, _len: usize) {} |
| 166 | + |
139 | 167 | /// Converts a reference to T into a slice of length 1 (without copying).
|
140 | 168 | #[stable(feature = "from_ref", since = "1.28.0")]
|
141 | 169 | #[rustc_const_unstable(feature = "const_slice_from_ref", issue = "90206")]
|
|
0 commit comments