@@ -288,10 +288,12 @@ impl<T> [T] {
288
288
/// Returns a reference to an element or subslice, without doing bounds
289
289
/// checking.
290
290
///
291
- /// This is generally not recommended, use with caution!
291
+ /// For a safe alternative see [`get`].
292
+ ///
293
+ /// # Safety
294
+ ///
292
295
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
293
296
/// even if the resulting reference is not used.
294
- /// For a safe alternative see [`get`].
295
297
///
296
298
/// [`get`]: #method.get
297
299
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
@@ -320,10 +322,12 @@ impl<T> [T] {
320
322
/// Returns a mutable reference to an element or subslice, without doing
321
323
/// bounds checking.
322
324
///
323
- /// This is generally not recommended, use with caution!
325
+ /// For a safe alternative see [`get_mut`].
326
+ ///
327
+ /// # Safety
328
+ ///
324
329
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
325
330
/// even if the resulting reference is not used.
326
- /// For a safe alternative see [`get_mut`].
327
331
///
328
332
/// [`get_mut`]: #method.get_mut
329
333
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
@@ -865,8 +869,9 @@ impl<T> [T] {
865
869
pub fn chunks_exact ( & self , chunk_size : usize ) -> ChunksExact < ' _ , T > {
866
870
assert_ne ! ( chunk_size, 0 ) ;
867
871
let rem = self . len ( ) % chunk_size;
868
- let len = self . len ( ) - rem;
869
- let ( fst, snd) = self . split_at ( len) ;
872
+ let fst_len = self . len ( ) - rem;
873
+ // SAFETY: 0 <= fst_len <= self.len() by construction above
874
+ let ( fst, snd) = unsafe { self . split_at_unchecked ( fst_len) } ;
870
875
ChunksExact { v : fst, rem : snd, chunk_size }
871
876
}
872
877
@@ -910,8 +915,9 @@ impl<T> [T] {
910
915
pub fn chunks_exact_mut ( & mut self , chunk_size : usize ) -> ChunksExactMut < ' _ , T > {
911
916
assert_ne ! ( chunk_size, 0 ) ;
912
917
let rem = self . len ( ) % chunk_size;
913
- let len = self . len ( ) - rem;
914
- let ( fst, snd) = self . split_at_mut ( len) ;
918
+ let fst_len = self . len ( ) - rem;
919
+ // SAFETY: 0 <= fst_len <= self.len() by construction above
920
+ let ( fst, snd) = unsafe { self . split_at_mut_unchecked ( fst_len) } ;
915
921
ChunksExactMut { v : fst, rem : snd, chunk_size }
916
922
}
917
923
@@ -1063,7 +1069,8 @@ impl<T> [T] {
1063
1069
pub fn rchunks_exact ( & self , chunk_size : usize ) -> RChunksExact < ' _ , T > {
1064
1070
assert ! ( chunk_size != 0 ) ;
1065
1071
let rem = self . len ( ) % chunk_size;
1066
- let ( fst, snd) = self . split_at ( rem) ;
1072
+ // SAFETY: 0 <= rem <= self.len() by construction above
1073
+ let ( fst, snd) = unsafe { self . split_at_unchecked ( rem) } ;
1067
1074
RChunksExact { v : snd, rem : fst, chunk_size }
1068
1075
}
1069
1076
@@ -1108,7 +1115,8 @@ impl<T> [T] {
1108
1115
pub fn rchunks_exact_mut ( & mut self , chunk_size : usize ) -> RChunksExactMut < ' _ , T > {
1109
1116
assert ! ( chunk_size != 0 ) ;
1110
1117
let rem = self . len ( ) % chunk_size;
1111
- let ( fst, snd) = self . split_at_mut ( rem) ;
1118
+ // SAFETY: 0 <= rem <= self.len() by construction above
1119
+ let ( fst, snd) = unsafe { self . split_at_mut_unchecked ( rem) } ;
1112
1120
RChunksExactMut { v : snd, rem : fst, chunk_size }
1113
1121
}
1114
1122
@@ -1129,26 +1137,29 @@ impl<T> [T] {
1129
1137
///
1130
1138
/// {
1131
1139
/// let (left, right) = v.split_at(0);
1132
- /// assert !(left == []);
1133
- /// assert !(right == [1, 2, 3, 4, 5, 6]);
1140
+ /// assert_eq !(left, []);
1141
+ /// assert_eq !(right, [1, 2, 3, 4, 5, 6]);
1134
1142
/// }
1135
1143
///
1136
1144
/// {
1137
1145
/// let (left, right) = v.split_at(2);
1138
- /// assert !(left == [1, 2]);
1139
- /// assert !(right == [3, 4, 5, 6]);
1146
+ /// assert_eq !(left, [1, 2]);
1147
+ /// assert_eq !(right, [3, 4, 5, 6]);
1140
1148
/// }
1141
1149
///
1142
1150
/// {
1143
1151
/// let (left, right) = v.split_at(6);
1144
- /// assert !(left == [1, 2, 3, 4, 5, 6]);
1145
- /// assert !(right == []);
1152
+ /// assert_eq !(left, [1, 2, 3, 4, 5, 6]);
1153
+ /// assert_eq !(right, []);
1146
1154
/// }
1147
1155
/// ```
1148
1156
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1149
1157
#[ inline]
1150
1158
pub fn split_at ( & self , mid : usize ) -> ( & [ T ] , & [ T ] ) {
1151
- ( & self [ ..mid] , & self [ mid..] )
1159
+ assert ! ( mid <= self . len( ) ) ;
1160
+ // SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
1161
+ // fulfills the requirements of `from_raw_parts_mut`.
1162
+ unsafe { self . split_at_unchecked ( mid) }
1152
1163
}
1153
1164
1154
1165
/// Divides one mutable slice into two at an index.
@@ -1168,26 +1179,115 @@ impl<T> [T] {
1168
1179
/// // scoped to restrict the lifetime of the borrows
1169
1180
/// {
1170
1181
/// let (left, right) = v.split_at_mut(2);
1171
- /// assert !(left == [1, 0]);
1172
- /// assert !(right == [3, 0, 5, 6]);
1182
+ /// assert_eq !(left, [1, 0]);
1183
+ /// assert_eq !(right, [3, 0, 5, 6]);
1173
1184
/// left[1] = 2;
1174
1185
/// right[1] = 4;
1175
1186
/// }
1176
- /// assert !(v == [1, 2, 3, 4, 5, 6]);
1187
+ /// assert_eq !(v, [1, 2, 3, 4, 5, 6]);
1177
1188
/// ```
1178
1189
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
1179
1190
#[ inline]
1180
1191
pub fn split_at_mut ( & mut self , mid : usize ) -> ( & mut [ T ] , & mut [ T ] ) {
1181
- let len = self . len ( ) ;
1182
- let ptr = self . as_mut_ptr ( ) ;
1183
-
1192
+ assert ! ( mid <= self . len( ) ) ;
1184
1193
// SAFETY: `[ptr; mid]` and `[mid; len]` are inside `self`, which
1185
1194
// fulfills the requirements of `from_raw_parts_mut`.
1186
- unsafe {
1187
- assert ! ( mid <= len ) ;
1195
+ unsafe { self . split_at_mut_unchecked ( mid ) }
1196
+ }
1188
1197
1189
- ( from_raw_parts_mut ( ptr, mid) , from_raw_parts_mut ( ptr. add ( mid) , len - mid) )
1190
- }
1198
+ /// Divides one slice into two at an index, without doing bounds checking.
1199
+ ///
1200
+ /// The first will contain all indices from `[0, mid)` (excluding
1201
+ /// the index `mid` itself) and the second will contain all
1202
+ /// indices from `[mid, len)` (excluding the index `len` itself).
1203
+ ///
1204
+ /// For a safe alternative see [`split_at`].
1205
+ ///
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
+ ///
1212
+ /// [`split_at`]: #method.split_at
1213
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1214
+ ///
1215
+ /// # Examples
1216
+ ///
1217
+ /// ```compile_fail
1218
+ /// #![feature(slice_split_at_unchecked)]
1219
+ ///
1220
+ /// let v = [1, 2, 3, 4, 5, 6];
1221
+ ///
1222
+ /// unsafe {
1223
+ /// let (left, right) = v.split_at_unchecked(0);
1224
+ /// assert_eq!(left, []);
1225
+ /// assert_eq!(right, [1, 2, 3, 4, 5, 6]);
1226
+ /// }
1227
+ ///
1228
+ /// unsafe {
1229
+ /// let (left, right) = v.split_at_unchecked(2);
1230
+ /// assert_eq!(left, [1, 2]);
1231
+ /// assert_eq!(right, [3, 4, 5, 6]);
1232
+ /// }
1233
+ ///
1234
+ /// unsafe {
1235
+ /// let (left, right) = v.split_at_unchecked(6);
1236
+ /// assert_eq!(left, [1, 2, 3, 4, 5, 6]);
1237
+ /// assert_eq!(right, []);
1238
+ /// }
1239
+ /// ```
1240
+ #[ unstable( feature = "slice_split_at_unchecked" , reason = "new API" , issue = "76014" ) ]
1241
+ #[ inline]
1242
+ unsafe fn split_at_unchecked ( & self , mid : usize ) -> ( & [ T ] , & [ T ] ) {
1243
+ // SAFETY: Caller has to check that `0 <= mid <= self.len()`
1244
+ unsafe { ( self . get_unchecked ( ..mid) , self . get_unchecked ( mid..) ) }
1245
+ }
1246
+
1247
+ /// Divides one mutable slice into two at an index, without doing bounds checking.
1248
+ ///
1249
+ /// The first will contain all indices from `[0, mid)` (excluding
1250
+ /// the index `mid` itself) and the second will contain all
1251
+ /// indices from `[mid, len)` (excluding the index `len` itself).
1252
+ ///
1253
+ /// For a safe alternative see [`split_at_mut`].
1254
+ ///
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
+ ///
1261
+ /// [`split_at_mut`]: #method.split_at_mut
1262
+ /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
1263
+ ///
1264
+ /// # Examples
1265
+ ///
1266
+ /// ```compile_fail
1267
+ /// #![feature(slice_split_at_unchecked)]
1268
+ ///
1269
+ /// let mut v = [1, 0, 3, 0, 5, 6];
1270
+ /// // scoped to restrict the lifetime of the borrows
1271
+ /// unsafe {
1272
+ /// let (left, right) = v.split_at_mut_unchecked(2);
1273
+ /// assert_eq!(left, [1, 0]);
1274
+ /// assert_eq!(right, [3, 0, 5, 6]);
1275
+ /// left[1] = 2;
1276
+ /// right[1] = 4;
1277
+ /// }
1278
+ /// assert_eq!(v, [1, 2, 3, 4, 5, 6]);
1279
+ /// ```
1280
+ #[ unstable( feature = "slice_split_at_unchecked" , reason = "new API" , issue = "76014" ) ]
1281
+ #[ inline]
1282
+ unsafe fn split_at_mut_unchecked ( & mut self , mid : usize ) -> ( & mut [ T ] , & mut [ T ] ) {
1283
+ let len = self . len ( ) ;
1284
+ let ptr = self . as_mut_ptr ( ) ;
1285
+
1286
+ // SAFETY: Caller has to check that `0 <= mid <= self.len()`.
1287
+ //
1288
+ // `[ptr; mid]` and `[mid; len]` are not overlapping, so returning a mutable reference
1289
+ // is fine.
1290
+ unsafe { ( from_raw_parts_mut ( ptr, mid) , from_raw_parts_mut ( ptr. add ( mid) , len - mid) ) }
1191
1291
}
1192
1292
1193
1293
/// Returns an iterator over subslices separated by elements that match
0 commit comments