Skip to content

Commit 8d3cf92

Browse files
committed
Improve documentation of slice::get_unchecked() / split_at_unchecked()
Thanks to Ivan Tham, who gave the majority of these suggestions during their review.
1 parent d08996a commit 8d3cf92

File tree

1 file changed

+41
-31
lines changed

1 file changed

+41
-31
lines changed

library/core/src/slice/mod.rs

+41-31
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,12 @@ impl<T> [T] {
288288
/// Returns a reference to an element or subslice, without doing bounds
289289
/// checking.
290290
///
291-
/// This is generally not recommended, use with caution!
291+
/// For a safe alternative see [`get`].
292+
///
293+
/// # Safety
294+
///
292295
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
293296
/// even if the resulting reference is not used.
294-
/// For a safe alternative see [`get`].
295297
///
296298
/// [`get`]: #method.get
297299
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
@@ -320,10 +322,12 @@ impl<T> [T] {
320322
/// Returns a mutable reference to an element or subslice, without doing
321323
/// bounds checking.
322324
///
323-
/// This is generally not recommended, use with caution!
325+
/// For a safe alternative see [`get_mut`].
326+
///
327+
/// # Safety
328+
///
324329
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
325330
/// even if the resulting reference is not used.
326-
/// For a safe alternative see [`get_mut`].
327331
///
328332
/// [`get_mut`]: #method.get_mut
329333
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
@@ -1133,20 +1137,20 @@ impl<T> [T] {
11331137
///
11341138
/// {
11351139
/// let (left, right) = v.split_at(0);
1136-
/// assert!(left == []);
1137-
/// assert!(right == [1, 2, 3, 4, 5, 6]);
1140+
/// assert_eq!(left, []);
1141+
/// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
11381142
/// }
11391143
///
11401144
/// {
11411145
/// let (left, right) = v.split_at(2);
1142-
/// assert!(left == [1, 2]);
1143-
/// assert!(right == [3, 4, 5, 6]);
1146+
/// assert_eq!(left, [1, 2]);
1147+
/// assert_eq!(right, [3, 4, 5, 6]);
11441148
/// }
11451149
///
11461150
/// {
11471151
/// let (left, right) = v.split_at(6);
1148-
/// assert!(left == [1, 2, 3, 4, 5, 6]);
1149-
/// assert!(right == []);
1152+
/// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
1153+
/// assert_eq!(right, []);
11501154
/// }
11511155
/// ```
11521156
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1175,12 +1179,12 @@ impl<T> [T] {
11751179
/// // scoped to restrict the lifetime of the borrows
11761180
/// {
11771181
/// let (left, right) = v.split_at_mut(2);
1178-
/// assert!(left == [1, 0]);
1179-
/// assert!(right == [3, 0, 5, 6]);
1182+
/// assert_eq!(left, [1, 0]);
1183+
/// assert_eq!(right, [3, 0, 5, 6]);
11801184
/// left[1] = 2;
11811185
/// right[1] = 4;
11821186
/// }
1183-
/// assert!(v == [1, 2, 3, 4, 5, 6]);
1187+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
11841188
/// ```
11851189
#[stable(feature = "rust1", since = "1.0.0")]
11861190
#[inline]
@@ -1197,11 +1201,14 @@ impl<T> [T] {
11971201
/// the index `mid` itself) and the second will contain all
11981202
/// indices from `[mid, len)` (excluding the index `len` itself).
11991203
///
1200-
/// This is generally not recommended, use with caution!
1201-
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
1202-
/// even if the resulting reference is not used.
12031204
/// For a safe alternative see [`split_at`].
12041205
///
1206+
/// # Safety
1207+
///
1208+
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
1209+
/// even if the resulting reference is not used. The caller has to ensure that
1210+
/// `0 <= mid <= self.len()`.
1211+
///
12051212
/// [`split_at`]: #method.split_at
12061213
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
12071214
///
@@ -1214,26 +1221,26 @@ impl<T> [T] {
12141221
///
12151222
/// unsafe {
12161223
/// let (left, right) = v.split_at_unchecked(0);
1217-
/// assert!(left == []);
1218-
/// assert!(right == [1, 2, 3, 4, 5, 6]);
1224+
/// assert_eq!(left, []);
1225+
/// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
12191226
/// }
12201227
///
12211228
/// unsafe {
12221229
/// let (left, right) = v.split_at_unchecked(2);
1223-
/// assert!(left == [1, 2]);
1224-
/// assert!(right == [3, 4, 5, 6]);
1230+
/// assert_eq!(left, [1, 2]);
1231+
/// assert_eq!(right, [3, 4, 5, 6]);
12251232
/// }
12261233
///
12271234
/// unsafe {
12281235
/// let (left, right) = v.split_at_unchecked(6);
1229-
/// assert!(left == [1, 2, 3, 4, 5, 6]);
1230-
/// assert!(right == []);
1236+
/// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
1237+
/// assert_eq!(right, []);
12311238
/// }
12321239
/// ```
12331240
#[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
12341241
#[inline]
12351242
unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
1236-
// SAFETY: Caller has to check that 0 <= mid < self.len()
1243+
// SAFETY: Caller has to check that `0 <= mid <= self.len()`
12371244
unsafe { (self.get_unchecked(..mid), self.get_unchecked(mid..)) }
12381245
}
12391246

@@ -1243,11 +1250,14 @@ impl<T> [T] {
12431250
/// the index `mid` itself) and the second will contain all
12441251
/// indices from `[mid, len)` (excluding the index `len` itself).
12451252
///
1246-
/// This is generally not recommended, use with caution!
1247-
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
1248-
/// even if the resulting reference is not used.
12491253
/// For a safe alternative see [`split_at_mut`].
12501254
///
1255+
/// # Safety
1256+
///
1257+
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
1258+
/// even if the resulting reference is not used. The caller has to ensure that
1259+
/// `0 <= mid <= self.len()`.
1260+
///
12511261
/// [`split_at_mut`]: #method.split_at_mut
12521262
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
12531263
///
@@ -1260,22 +1270,22 @@ impl<T> [T] {
12601270
/// // scoped to restrict the lifetime of the borrows
12611271
/// unsafe {
12621272
/// let (left, right) = v.split_at_mut_unchecked(2);
1263-
/// assert!(left == [1, 0]);
1264-
/// assert!(right == [3, 0, 5, 6]);
1273+
/// assert_eq!(left, [1, 0]);
1274+
/// assert_eq!(right, [3, 0, 5, 6]);
12651275
/// left[1] = 2;
12661276
/// right[1] = 4;
12671277
/// }
1268-
/// assert!(v == [1, 2, 3, 4, 5, 6]);
1278+
/// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
12691279
/// ```
12701280
#[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
12711281
#[inline]
12721282
unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
12731283
let len = self.len();
12741284
let ptr = self.as_mut_ptr();
12751285

1276-
// SAFETY: Caller has to check that 0 <= mid < self.len().
1286+
// SAFETY: Caller has to check that `0 <= mid <= self.len()`.
12771287
//
1278-
// [ptr; mid] and [mid; len] are not overlapping, so returning a mutable reference
1288+
// `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
12791289
// is fine.
12801290
unsafe { (from_raw_parts_mut(ptr, mid), from_raw_parts_mut(ptr.add(mid), len - mid)) }
12811291
}

0 commit comments

Comments
 (0)