Skip to content

Commit bcd18f9

Browse files
committed
Move free functions to a new module
1 parent f376443 commit bcd18f9

File tree

3 files changed

+172
-173
lines changed

3 files changed

+172
-173
lines changed

library/core/src/slice/mod.rs

Lines changed: 12 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,12 @@
1717
//
1818
// * Inherent methods. This is where most of the slice API resides.
1919
// * Implementations of a few common traits with important slice ops.
20-
// * Definitions of a bunch of iterators.
21-
// * Free functions.
2220
// * The `raw` and `bytes` submodules.
2321
// * Boilerplate trait implementations.
2422

2523
use crate::cmp;
2624
use crate::cmp::Ordering::{self, Equal, Greater, Less};
27-
use crate::intrinsics::{assume, is_aligned_and_not_null};
28-
use crate::iter::*;
25+
use crate::intrinsics::assume;
2926
use crate::marker::{self, Copy, Sized};
3027
use crate::mem;
3128
use crate::ops::{self, Bound, FnMut, Range, RangeBounds};
@@ -44,6 +41,7 @@ use crate::result::Result::{Err, Ok};
4441
pub mod memchr;
4542

4643
mod iter;
44+
mod raw;
4745
mod rotate;
4846
mod sort;
4947

@@ -71,6 +69,16 @@ pub use iter::{ArrayChunks, ArrayChunksMut};
7169
#[unstable(feature = "split_inclusive", issue = "72360")]
7270
pub use iter::{SplitInclusive, SplitInclusiveMut};
7371

72+
#[stable(feature = "rust1", since = "1.0.0")]
73+
pub use raw::{from_raw_parts, from_raw_parts_mut};
74+
75+
#[stable(feature = "from_ref", since = "1.28.0")]
76+
pub use raw::{from_mut, from_ref};
77+
78+
// This function is public only because there is no other way to unit test heapsort.
79+
#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "none")]
80+
pub use sort::heapsort;
81+
7482
//
7583
// Extension traits
7684
//
@@ -3806,174 +3814,6 @@ impl<T> Default for &mut [T] {
38063814
}
38073815
}
38083816

3809-
//
3810-
// Free functions
3811-
//
3812-
3813-
/// Forms a slice from a pointer and a length.
3814-
///
3815-
/// The `len` argument is the number of **elements**, not the number of bytes.
3816-
///
3817-
/// # Safety
3818-
///
3819-
/// Behavior is undefined if any of the following conditions are violated:
3820-
///
3821-
/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
3822-
/// and it must be properly aligned. This means in particular:
3823-
///
3824-
/// * The entire memory range of this slice must be contained within a single allocated object!
3825-
/// Slices can never span across multiple allocated objects. See [below](#incorrect-usage)
3826-
/// for an example incorrectly not taking this into account.
3827-
/// * `data` must be non-null and aligned even for zero-length slices. One
3828-
/// reason for this is that enum layout optimizations may rely on references
3829-
/// (including slices of any length) being aligned and non-null to distinguish
3830-
/// them from other data. You can obtain a pointer that is usable as `data`
3831-
/// for zero-length slices using [`NonNull::dangling()`].
3832-
///
3833-
/// * `data` must point to `len` consecutive properly initialized values of type `T`.
3834-
///
3835-
/// * The memory referenced by the returned slice must not be mutated for the duration
3836-
/// of lifetime `'a`, except inside an `UnsafeCell`.
3837-
///
3838-
/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
3839-
/// See the safety documentation of [`pointer::offset`].
3840-
///
3841-
/// # Caveat
3842-
///
3843-
/// The lifetime for the returned slice is inferred from its usage. To
3844-
/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
3845-
/// source lifetime is safe in the context, such as by providing a helper
3846-
/// function taking the lifetime of a host value for the slice, or by explicit
3847-
/// annotation.
3848-
///
3849-
/// # Examples
3850-
///
3851-
/// ```
3852-
/// use std::slice;
3853-
///
3854-
/// // manifest a slice for a single element
3855-
/// let x = 42;
3856-
/// let ptr = &x as *const _;
3857-
/// let slice = unsafe { slice::from_raw_parts(ptr, 1) };
3858-
/// assert_eq!(slice[0], 42);
3859-
/// ```
3860-
///
3861-
/// ### Incorrect usage
3862-
///
3863-
/// The following `join_slices` function is **unsound** ⚠️
3864-
///
3865-
/// ```rust,no_run
3866-
/// use std::slice;
3867-
///
3868-
/// fn join_slices<'a, T>(fst: &'a [T], snd: &'a [T]) -> &'a [T] {
3869-
/// let fst_end = fst.as_ptr().wrapping_add(fst.len());
3870-
/// let snd_start = snd.as_ptr();
3871-
/// assert_eq!(fst_end, snd_start, "Slices must be contiguous!");
3872-
/// unsafe {
3873-
/// // The assertion above ensures `fst` and `snd` are contiguous, but they might
3874-
/// // still be contained within _different allocated objects_, in which case
3875-
/// // creating this slice is undefined behavior.
3876-
/// slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len())
3877-
/// }
3878-
/// }
3879-
///
3880-
/// fn main() {
3881-
/// // `a` and `b` are different allocated objects...
3882-
/// let a = 42;
3883-
/// let b = 27;
3884-
/// // ... which may nevertheless be laid out contiguously in memory: | a | b |
3885-
/// let _ = join_slices(slice::from_ref(&a), slice::from_ref(&b)); // UB
3886-
/// }
3887-
/// ```
3888-
///
3889-
/// [valid]: ptr#safety
3890-
/// [`NonNull::dangling()`]: ptr::NonNull::dangling
3891-
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
3892-
#[inline]
3893-
#[stable(feature = "rust1", since = "1.0.0")]
3894-
pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
3895-
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
3896-
debug_assert!(
3897-
mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
3898-
"attempt to create slice covering at least half the address space"
3899-
);
3900-
// SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
3901-
unsafe { &*ptr::slice_from_raw_parts(data, len) }
3902-
}
3903-
3904-
/// Performs the same functionality as [`from_raw_parts`], except that a
3905-
/// mutable slice is returned.
3906-
///
3907-
/// # Safety
3908-
///
3909-
/// Behavior is undefined if any of the following conditions are violated:
3910-
///
3911-
/// * `data` must be [valid] for boths reads and writes for `len * mem::size_of::<T>()` many bytes,
3912-
/// and it must be properly aligned. This means in particular:
3913-
///
3914-
/// * The entire memory range of this slice must be contained within a single allocated object!
3915-
/// Slices can never span across multiple allocated objects.
3916-
/// * `data` must be non-null and aligned even for zero-length slices. One
3917-
/// reason for this is that enum layout optimizations may rely on references
3918-
/// (including slices of any length) being aligned and non-null to distinguish
3919-
/// them from other data. You can obtain a pointer that is usable as `data`
3920-
/// for zero-length slices using [`NonNull::dangling()`].
3921-
///
3922-
/// * `data` must point to `len` consecutive properly initialized values of type `T`.
3923-
///
3924-
/// * The memory referenced by the returned slice must not be accessed through any other pointer
3925-
/// (not derived from the return value) for the duration of lifetime `'a`.
3926-
/// Both read and write accesses are forbidden.
3927-
///
3928-
/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
3929-
/// See the safety documentation of [`pointer::offset`].
3930-
///
3931-
/// [valid]: ptr#safety
3932-
/// [`NonNull::dangling()`]: ptr::NonNull::dangling
3933-
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
3934-
#[inline]
3935-
#[stable(feature = "rust1", since = "1.0.0")]
3936-
pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
3937-
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
3938-
debug_assert!(
3939-
mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
3940-
"attempt to create slice covering at least half the address space"
3941-
);
3942-
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
3943-
unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
3944-
}
3945-
3946-
/// Converts a reference to T into a slice of length 1 (without copying).
3947-
#[stable(feature = "from_ref", since = "1.28.0")]
3948-
pub fn from_ref<T>(s: &T) -> &[T] {
3949-
// SAFETY: a reference is guaranteed to be valid for reads. The returned
3950-
// reference cannot be mutated as it is an immutable reference.
3951-
// `mem::size_of::<T>()` cannot be larger than `isize::MAX`.
3952-
// Thus the call to `from_raw_parts` is safe.
3953-
unsafe { from_raw_parts(s, 1) }
3954-
}
3955-
3956-
/// Converts a reference to T into a slice of length 1 (without copying).
3957-
#[stable(feature = "from_ref", since = "1.28.0")]
3958-
pub fn from_mut<T>(s: &mut T) -> &mut [T] {
3959-
// SAFETY: a mutable reference is guaranteed to be valid for writes.
3960-
// The reference cannot be accessed by another pointer as it is an mutable reference.
3961-
// `mem::size_of::<T>()` cannot be larger than `isize::MAX`.
3962-
// Thus the call to `from_raw_parts_mut` is safe.
3963-
unsafe { from_raw_parts_mut(s, 1) }
3964-
}
3965-
3966-
// This function is public only because there is no other way to unit test heapsort.
3967-
#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "none")]
3968-
#[doc(hidden)]
3969-
pub fn heapsort<T, F>(v: &mut [T], mut is_less: F)
3970-
where
3971-
F: FnMut(&T, &T) -> bool,
3972-
{
3973-
sort::heapsort(v, &mut is_less);
3974-
}
3975-
3976-
//
39773817
// Comparison traits
39783818
//
39793819

library/core/src/slice/raw.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
//! Free functions to create `&[T]` and `&mut [T]`.
2+
3+
use crate::intrinsics::is_aligned_and_not_null;
4+
use crate::mem;
5+
use crate::ptr;
6+
7+
/// Forms a slice from a pointer and a length.
8+
///
9+
/// The `len` argument is the number of **elements**, not the number of bytes.
10+
///
11+
/// # Safety
12+
///
13+
/// Behavior is undefined if any of the following conditions are violated:
14+
///
15+
/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
16+
/// and it must be properly aligned. This means in particular:
17+
///
18+
/// * The entire memory range of this slice must be contained within a single allocated object!
19+
/// Slices can never span across multiple allocated objects. See [below](#incorrect-usage)
20+
/// for an example incorrectly not taking this into account.
21+
/// * `data` must be non-null and aligned even for zero-length slices. One
22+
/// reason for this is that enum layout optimizations may rely on references
23+
/// (including slices of any length) being aligned and non-null to distinguish
24+
/// them from other data. You can obtain a pointer that is usable as `data`
25+
/// for zero-length slices using [`NonNull::dangling()`].
26+
///
27+
/// * `data` must point to `len` consecutive properly initialized values of type `T`.
28+
///
29+
/// * The memory referenced by the returned slice must not be mutated for the duration
30+
/// of lifetime `'a`, except inside an `UnsafeCell`.
31+
///
32+
/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
33+
/// See the safety documentation of [`pointer::offset`].
34+
///
35+
/// # Caveat
36+
///
37+
/// The lifetime for the returned slice is inferred from its usage. To
38+
/// prevent accidental misuse, it's suggested to tie the lifetime to whichever
39+
/// source lifetime is safe in the context, such as by providing a helper
40+
/// function taking the lifetime of a host value for the slice, or by explicit
41+
/// annotation.
42+
///
43+
/// # Examples
44+
///
45+
/// ```
46+
/// use std::slice;
47+
///
48+
/// // manifest a slice for a single element
49+
/// let x = 42;
50+
/// let ptr = &x as *const _;
51+
/// let slice = unsafe { slice::from_raw_parts(ptr, 1) };
52+
/// assert_eq!(slice[0], 42);
53+
/// ```
54+
///
55+
/// ### Incorrect usage
56+
///
57+
/// The following `join_slices` function is **unsound** ⚠️
58+
///
59+
/// ```rust,no_run
60+
/// use std::slice;
61+
///
62+
/// fn join_slices<'a, T>(fst: &'a [T], snd: &'a [T]) -> &'a [T] {
63+
/// let fst_end = fst.as_ptr().wrapping_add(fst.len());
64+
/// let snd_start = snd.as_ptr();
65+
/// assert_eq!(fst_end, snd_start, "Slices must be contiguous!");
66+
/// unsafe {
67+
/// // The assertion above ensures `fst` and `snd` are contiguous, but they might
68+
/// // still be contained within _different allocated objects_, in which case
69+
/// // creating this slice is undefined behavior.
70+
/// slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len())
71+
/// }
72+
/// }
73+
///
74+
/// fn main() {
75+
/// // `a` and `b` are different allocated objects...
76+
/// let a = 42;
77+
/// let b = 27;
78+
/// // ... which may nevertheless be laid out contiguously in memory: | a | b |
79+
/// let _ = join_slices(slice::from_ref(&a), slice::from_ref(&b)); // UB
80+
/// }
81+
/// ```
82+
///
83+
/// [valid]: ptr#safety
84+
/// [`NonNull::dangling()`]: ptr::NonNull::dangling
85+
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
86+
#[inline]
87+
#[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+
);
94+
// SAFETY: the caller must uphold the safety contract for `from_raw_parts`.
95+
unsafe { &*ptr::slice_from_raw_parts(data, len) }
96+
}
97+
98+
/// Performs the same functionality as [`from_raw_parts`], except that a
99+
/// mutable slice is returned.
100+
///
101+
/// # Safety
102+
///
103+
/// Behavior is undefined if any of the following conditions are violated:
104+
///
105+
/// * `data` must be [valid] for boths reads and writes for `len * mem::size_of::<T>()` many bytes,
106+
/// and it must be properly aligned. This means in particular:
107+
///
108+
/// * The entire memory range of this slice must be contained within a single allocated object!
109+
/// Slices can never span across multiple allocated objects.
110+
/// * `data` must be non-null and aligned even for zero-length slices. One
111+
/// reason for this is that enum layout optimizations may rely on references
112+
/// (including slices of any length) being aligned and non-null to distinguish
113+
/// them from other data. You can obtain a pointer that is usable as `data`
114+
/// for zero-length slices using [`NonNull::dangling()`].
115+
///
116+
/// * `data` must point to `len` consecutive properly initialized values of type `T`.
117+
///
118+
/// * The memory referenced by the returned slice must not be accessed through any other pointer
119+
/// (not derived from the return value) for the duration of lifetime `'a`.
120+
/// Both read and write accesses are forbidden.
121+
///
122+
/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
123+
/// See the safety documentation of [`pointer::offset`].
124+
///
125+
/// [valid]: ptr#safety
126+
/// [`NonNull::dangling()`]: ptr::NonNull::dangling
127+
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
128+
#[inline]
129+
#[stable(feature = "rust1", since = "1.0.0")]
130+
pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
131+
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
132+
debug_assert!(
133+
mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
134+
"attempt to create slice covering at least half the address space"
135+
);
136+
// SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`.
137+
unsafe { &mut *ptr::slice_from_raw_parts_mut(data, len) }
138+
}
139+
140+
/// Converts a reference to T into a slice of length 1 (without copying).
141+
#[stable(feature = "from_ref", since = "1.28.0")]
142+
pub fn from_ref<T>(s: &T) -> &[T] {
143+
// SAFETY: a reference is guaranteed to be valid for reads. The returned
144+
// reference cannot be mutated as it is an immutable reference.
145+
// `mem::size_of::<T>()` cannot be larger than `isize::MAX`.
146+
// Thus the call to `from_raw_parts` is safe.
147+
unsafe { from_raw_parts(s, 1) }
148+
}
149+
150+
/// Converts a reference to T into a slice of length 1 (without copying).
151+
#[stable(feature = "from_ref", since = "1.28.0")]
152+
pub fn from_mut<T>(s: &mut T) -> &mut [T] {
153+
// SAFETY: a mutable reference is guaranteed to be valid for writes.
154+
// The reference cannot be accessed by another pointer as it is an mutable reference.
155+
// `mem::size_of::<T>()` cannot be larger than `isize::MAX`.
156+
// Thus the call to `from_raw_parts_mut` is safe.
157+
unsafe { from_raw_parts_mut(s, 1) }
158+
}

library/core/src/slice/sort.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ where
180180

181181
/// Sorts `v` using heapsort, which guarantees *O*(*n* \* log(*n*)) worst-case.
182182
#[cold]
183-
pub fn heapsort<T, F>(v: &mut [T], is_less: &mut F)
183+
#[unstable(feature = "sort_internals", reason = "internal to sort module", issue = "none")]
184+
pub fn heapsort<T, F>(v: &mut [T], mut is_less: F)
184185
where
185186
F: FnMut(&T, &T) -> bool,
186187
{

0 commit comments

Comments
 (0)