@@ -972,7 +972,6 @@ impl<T> [T] {
972
972
///
973
973
/// This may only be called when
974
974
/// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).
975
- /// - `N != 0`.
976
975
///
977
976
/// # Examples
978
977
///
@@ -990,14 +989,28 @@ impl<T> [T] {
990
989
///
991
990
/// // These would be unsound:
992
991
/// // let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
993
- /// // let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
994
992
/// ```
993
+ ///
994
+ /// It doesn't compile if chunk size is zero:
995
+ /// ```compile_fail
996
+ /// #![feature(slice_as_chunks)]
997
+ /// const N: usize = 0;
998
+ /// let slice = [1, 2, 3, 4];
999
+ /// let _ = unsafe{
1000
+ /// slice.as_chunks_unchecked::<N>()
1001
+ /// };
1002
+ /// ```
1003
+ ///
995
1004
#[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
996
1005
#[ inline]
997
1006
#[ must_use]
998
1007
pub const unsafe fn as_chunks_unchecked < const N : usize > ( & self ) -> & [ [ T ; N ] ] {
1008
+ const {
1009
+ assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1010
+ }
999
1011
let this = self ;
1000
- // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
1012
+ // SAFETY: Caller must guarantee that `N` exactly divides the slice length
1013
+ // `N` cannot be zero because we checked it using compile assert above.
1001
1014
let new_len = unsafe {
1002
1015
assert_unsafe_precondition ! (
1003
1016
"slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks" ,
@@ -1014,11 +1027,6 @@ impl<T> [T] {
1014
1027
/// starting at the beginning of the slice,
1015
1028
/// and a remainder slice with length strictly less than `N`.
1016
1029
///
1017
- /// # Panics
1018
- ///
1019
- /// Panics if `N` is 0. This check will most probably get changed to a compile time
1020
- /// error before this method gets stabilized.
1021
- ///
1022
1030
/// # Examples
1023
1031
///
1024
1032
/// ```
@@ -1039,16 +1047,28 @@ impl<T> [T] {
1039
1047
/// };
1040
1048
/// assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
1041
1049
/// ```
1050
+ ///
1051
+ /// It doesn't compile if chunk size is zero:
1052
+ /// ```compile_fail
1053
+ /// #![feature(slice_as_chunks)]
1054
+ /// const N: usize = 0;
1055
+ /// let slice = [1, 2, 3, 4];
1056
+ /// let _ = slice.as_chunks::<N>();
1057
+ /// ```
1058
+ ///
1042
1059
#[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
1043
1060
#[ inline]
1044
1061
#[ track_caller]
1045
1062
#[ must_use]
1046
1063
pub const fn as_chunks < const N : usize > ( & self ) -> ( & [ [ T ; N ] ] , & [ T ] ) {
1047
- assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1064
+ const {
1065
+ assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1066
+ }
1048
1067
let len = self . len ( ) / N ;
1049
1068
let ( multiple_of_n, remainder) = self . split_at ( len * N ) ;
1050
- // SAFETY: We already panicked for zero, and ensured by construction
1069
+ // SAFETY: It is ensured by construction
1051
1070
// that the length of the subslice is a multiple of N.
1071
+ // `N` cannot be zero because we checked it using compile assert above.
1052
1072
let array_slice = unsafe { multiple_of_n. as_chunks_unchecked ( ) } ;
1053
1073
( array_slice, remainder)
1054
1074
}
@@ -1071,16 +1091,28 @@ impl<T> [T] {
1071
1091
/// assert_eq!(remainder, &['l']);
1072
1092
/// assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
1073
1093
/// ```
1094
+ ///
1095
+ /// It doesn't compile if chunk size is zero:
1096
+ /// ```compile_fail
1097
+ /// #![feature(slice_as_chunks)]
1098
+ /// const N: usize = 0;
1099
+ /// let slice = [1, 2, 3, 4];
1100
+ /// let _ = slice.as_rchunks::<N>();
1101
+ /// ```
1102
+ ///
1074
1103
#[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
1075
1104
#[ inline]
1076
1105
#[ track_caller]
1077
1106
#[ must_use]
1078
1107
pub const fn as_rchunks < const N : usize > ( & self ) -> ( & [ T ] , & [ [ T ; N ] ] ) {
1079
- assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1108
+ const {
1109
+ assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1110
+ }
1080
1111
let len = self . len ( ) / N ;
1081
1112
let ( remainder, multiple_of_n) = self . split_at ( self . len ( ) - len * N ) ;
1082
- // SAFETY: We already panicked for zero, and ensured by construction
1113
+ // SAFETY: It is ensured by construction
1083
1114
// that the length of the subslice is a multiple of N.
1115
+ // `N` cannot be zero because we checked it using compile assert above.
1084
1116
let array_slice = unsafe { multiple_of_n. as_chunks_unchecked ( ) } ;
1085
1117
( remainder, array_slice)
1086
1118
}
@@ -1094,11 +1126,6 @@ impl<T> [T] {
1094
1126
///
1095
1127
/// This method is the const generic equivalent of [`chunks_exact`].
1096
1128
///
1097
- /// # Panics
1098
- ///
1099
- /// Panics if `N` is 0. This check will most probably get changed to a compile time
1100
- /// error before this method gets stabilized.
1101
- ///
1102
1129
/// # Examples
1103
1130
///
1104
1131
/// ```
@@ -1111,12 +1138,22 @@ impl<T> [T] {
1111
1138
/// assert_eq!(iter.remainder(), &['m']);
1112
1139
/// ```
1113
1140
///
1141
+ /// It doesn't compile if chunk size is zero:
1142
+ /// ```compile_fail
1143
+ /// #![feature(array_chunks)]
1144
+ /// const N: usize = 0;
1145
+ /// let slice = [1, 2, 3, 4];
1146
+ /// let _ = slice.array_chunks::<N>();
1147
+ /// ```
1148
+ ///
1114
1149
/// [`chunks_exact`]: slice::chunks_exact
1115
1150
#[ unstable( feature = "array_chunks" , issue = "74985" ) ]
1116
1151
#[ inline]
1117
1152
#[ track_caller]
1118
1153
pub fn array_chunks < const N : usize > ( & self ) -> ArrayChunks < ' _ , T , N > {
1119
- assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1154
+ const {
1155
+ assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1156
+ }
1120
1157
ArrayChunks :: new ( self )
1121
1158
}
1122
1159
@@ -1127,7 +1164,6 @@ impl<T> [T] {
1127
1164
///
1128
1165
/// This may only be called when
1129
1166
/// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).
1130
- /// - `N != 0`.
1131
1167
///
1132
1168
/// # Examples
1133
1169
///
@@ -1147,14 +1183,28 @@ impl<T> [T] {
1147
1183
///
1148
1184
/// // These would be unsound:
1149
1185
/// // let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
1150
- /// // let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
1151
1186
/// ```
1187
+ ///
1188
+ /// It doesn't compile if chunk size is zero:
1189
+ /// ```compile_fail
1190
+ /// #![feature(slice_as_chunks)]
1191
+ /// const N: usize = 0;
1192
+ /// let mut slice = [1, 2, 3, 4];
1193
+ /// let _ = unsafe{
1194
+ /// slice.as_chunks_unchecked_mut::<N>();
1195
+ /// };
1196
+ /// ```
1197
+ ///
1152
1198
#[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
1153
1199
#[ inline]
1154
1200
#[ must_use]
1155
1201
pub const unsafe fn as_chunks_unchecked_mut < const N : usize > ( & mut self ) -> & mut [ [ T ; N ] ] {
1202
+ const {
1203
+ assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1204
+ }
1156
1205
let this = & * self ;
1157
- // SAFETY: Caller must guarantee that `N` is nonzero and exactly divides the slice length
1206
+ // SAFETY: Caller must guarantee that `N` exactly divides the slice length
1207
+ // `N` cannot be zero because we checked it using compile assert above.
1158
1208
let new_len = unsafe {
1159
1209
assert_unsafe_precondition ! (
1160
1210
"slice::as_chunks_unchecked_mut requires `N != 0` and the slice to split exactly into `N`-element chunks" ,
@@ -1171,11 +1221,6 @@ impl<T> [T] {
1171
1221
/// starting at the beginning of the slice,
1172
1222
/// and a remainder slice with length strictly less than `N`.
1173
1223
///
1174
- /// # Panics
1175
- ///
1176
- /// Panics if `N` is 0. This check will most probably get changed to a compile time
1177
- /// error before this method gets stabilized.
1178
- ///
1179
1224
/// # Examples
1180
1225
///
1181
1226
/// ```
@@ -1191,16 +1236,28 @@ impl<T> [T] {
1191
1236
/// }
1192
1237
/// assert_eq!(v, &[1, 1, 2, 2, 9]);
1193
1238
/// ```
1239
+ ///
1240
+ /// It doesn't compile if chunk size is zero:
1241
+ /// ```compile_fail
1242
+ /// #![feature(slice_as_chunks)]
1243
+ /// const N: usize = 0;
1244
+ /// let mut slice = [1, 2, 3, 4];
1245
+ /// let _ = slice.as_chunks_mut::<N>();
1246
+ /// ```
1247
+ ///
1194
1248
#[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
1195
1249
#[ inline]
1196
1250
#[ track_caller]
1197
1251
#[ must_use]
1198
1252
pub const fn as_chunks_mut < const N : usize > ( & mut self ) -> ( & mut [ [ T ; N ] ] , & mut [ T ] ) {
1199
- assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1253
+ const {
1254
+ assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1255
+ }
1200
1256
let len = self . len ( ) / N ;
1201
1257
let ( multiple_of_n, remainder) = self . split_at_mut ( len * N ) ;
1202
- // SAFETY: We already panicked for zero, and ensured by construction
1258
+ // SAFETY: It is ensured by construction
1203
1259
// that the length of the subslice is a multiple of N.
1260
+ // `N` cannot be zero because we checked it using compile assert above.
1204
1261
let array_slice = unsafe { multiple_of_n. as_chunks_unchecked_mut ( ) } ;
1205
1262
( array_slice, remainder)
1206
1263
}
@@ -1209,11 +1266,6 @@ impl<T> [T] {
1209
1266
/// starting at the end of the slice,
1210
1267
/// and a remainder slice with length strictly less than `N`.
1211
1268
///
1212
- /// # Panics
1213
- ///
1214
- /// Panics if `N` is 0. This check will most probably get changed to a compile time
1215
- /// error before this method gets stabilized.
1216
- ///
1217
1269
/// # Examples
1218
1270
///
1219
1271
/// ```
@@ -1229,16 +1281,28 @@ impl<T> [T] {
1229
1281
/// }
1230
1282
/// assert_eq!(v, &[9, 1, 1, 2, 2]);
1231
1283
/// ```
1284
+ ///
1285
+ /// It doesn't compile if chunk size is zero:
1286
+ /// ```compile_fail
1287
+ /// #![feature(slice_as_chunks)]
1288
+ /// const N: usize = 0;
1289
+ /// let mut slice = [1, 2, 3, 4];
1290
+ /// let _ = slice.as_rchunks_mut::<N>();
1291
+ /// ```
1292
+ ///
1232
1293
#[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
1233
1294
#[ inline]
1234
1295
#[ track_caller]
1235
1296
#[ must_use]
1236
1297
pub const fn as_rchunks_mut < const N : usize > ( & mut self ) -> ( & mut [ T ] , & mut [ [ T ; N ] ] ) {
1237
- assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1298
+ const {
1299
+ assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1300
+ }
1238
1301
let len = self . len ( ) / N ;
1239
1302
let ( remainder, multiple_of_n) = self . split_at_mut ( self . len ( ) - len * N ) ;
1240
- // SAFETY: We already panicked for zero, and ensured by construction
1303
+ // SAFETY: It is ensured by construction
1241
1304
// that the length of the subslice is a multiple of N.
1305
+ // `N` cannot be zero because we checked it using compile assert above.
1242
1306
let array_slice = unsafe { multiple_of_n. as_chunks_unchecked_mut ( ) } ;
1243
1307
( remainder, array_slice)
1244
1308
}
@@ -1252,11 +1316,6 @@ impl<T> [T] {
1252
1316
///
1253
1317
/// This method is the const generic equivalent of [`chunks_exact_mut`].
1254
1318
///
1255
- /// # Panics
1256
- ///
1257
- /// Panics if `N` is 0. This check will most probably get changed to a compile time
1258
- /// error before this method gets stabilized.
1259
- ///
1260
1319
/// # Examples
1261
1320
///
1262
1321
/// ```
@@ -1271,12 +1330,22 @@ impl<T> [T] {
1271
1330
/// assert_eq!(v, &[1, 1, 2, 2, 0]);
1272
1331
/// ```
1273
1332
///
1333
+ /// It doesn't compile if chunk size is zero:
1334
+ /// ```compile_fail
1335
+ /// #![feature(array_chunks)]
1336
+ /// const N: usize = 0;
1337
+ /// let mut slice = [1, 2, 3, 4];
1338
+ /// let _ = slice.array_chunks_mut::<N>();
1339
+ /// ```
1340
+ ///
1274
1341
/// [`chunks_exact_mut`]: slice::chunks_exact_mut
1275
1342
#[ unstable( feature = "array_chunks" , issue = "74985" ) ]
1276
1343
#[ inline]
1277
1344
#[ track_caller]
1278
1345
pub fn array_chunks_mut < const N : usize > ( & mut self ) -> ArrayChunksMut < ' _ , T , N > {
1279
- assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1346
+ const {
1347
+ assert ! ( N != 0 , "chunk size must be non-zero" ) ;
1348
+ }
1280
1349
ArrayChunksMut :: new ( self )
1281
1350
}
1282
1351
@@ -1287,11 +1356,6 @@ impl<T> [T] {
1287
1356
///
1288
1357
/// If `N` is greater than the size of the slice, it will return no windows.
1289
1358
///
1290
- /// # Panics
1291
- ///
1292
- /// Panics if `N` is 0. This check will most probably get changed to a compile time
1293
- /// error before this method gets stabilized.
1294
- ///
1295
1359
/// # Examples
1296
1360
///
1297
1361
/// ```
@@ -1304,12 +1368,22 @@ impl<T> [T] {
1304
1368
/// assert!(iter.next().is_none());
1305
1369
/// ```
1306
1370
///
1371
+ /// It doesn't compile if window size is zero:
1372
+ /// ```compile_fail
1373
+ /// #![feature(array_windows)]
1374
+ /// const N: usize = 0;
1375
+ /// let slice = [0, 1, 2, 3];
1376
+ /// let _ = slice.array_windows::<N>();
1377
+ /// ```
1378
+ ///
1307
1379
/// [`windows`]: slice::windows
1308
1380
#[ unstable( feature = "array_windows" , issue = "75027" ) ]
1309
1381
#[ inline]
1310
1382
#[ track_caller]
1311
1383
pub fn array_windows < const N : usize > ( & self ) -> ArrayWindows < ' _ , T , N > {
1312
- assert ! ( N != 0 , "window size must be non-zero" ) ;
1384
+ const {
1385
+ assert ! ( N != 0 , "window size must be non-zero" ) ;
1386
+ }
1313
1387
ArrayWindows :: new ( self )
1314
1388
}
1315
1389
0 commit comments