@@ -972,7 +972,6 @@ impl<T> [T] {
972972 ///
973973 /// This may only be called when
974974 /// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).
975- /// - `N != 0`.
976975 ///
977976 /// # Examples
978977 ///
@@ -990,14 +989,28 @@ impl<T> [T] {
990989 ///
991990 /// // These would be unsound:
992991 /// // 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
994992 /// ```
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+ ///
9951004 #[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
9961005 #[ inline]
9971006 #[ must_use]
9981007 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+ }
9991011 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.
10011014 let new_len = unsafe {
10021015 assert_unsafe_precondition ! (
10031016 "slice::as_chunks_unchecked requires `N != 0` and the slice to split exactly into `N`-element chunks" ,
@@ -1014,11 +1027,6 @@ impl<T> [T] {
10141027 /// starting at the beginning of the slice,
10151028 /// and a remainder slice with length strictly less than `N`.
10161029 ///
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- ///
10221030 /// # Examples
10231031 ///
10241032 /// ```
@@ -1039,16 +1047,28 @@ impl<T> [T] {
10391047 /// };
10401048 /// assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
10411049 /// ```
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+ ///
10421059 #[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
10431060 #[ inline]
10441061 #[ track_caller]
10451062 #[ must_use]
10461063 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+ }
10481067 let len = self . len ( ) / N ;
10491068 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
10511070 // that the length of the subslice is a multiple of N.
1071+ // `N` cannot be zero because we checked it using compile assert above.
10521072 let array_slice = unsafe { multiple_of_n. as_chunks_unchecked ( ) } ;
10531073 ( array_slice, remainder)
10541074 }
@@ -1071,16 +1091,28 @@ impl<T> [T] {
10711091 /// assert_eq!(remainder, &['l']);
10721092 /// assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
10731093 /// ```
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+ ///
10741103 #[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
10751104 #[ inline]
10761105 #[ track_caller]
10771106 #[ must_use]
10781107 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+ }
10801111 let len = self . len ( ) / N ;
10811112 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
10831114 // that the length of the subslice is a multiple of N.
1115+ // `N` cannot be zero because we checked it using compile assert above.
10841116 let array_slice = unsafe { multiple_of_n. as_chunks_unchecked ( ) } ;
10851117 ( remainder, array_slice)
10861118 }
@@ -1094,11 +1126,6 @@ impl<T> [T] {
10941126 ///
10951127 /// This method is the const generic equivalent of [`chunks_exact`].
10961128 ///
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- ///
11021129 /// # Examples
11031130 ///
11041131 /// ```
@@ -1111,12 +1138,22 @@ impl<T> [T] {
11111138 /// assert_eq!(iter.remainder(), &['m']);
11121139 /// ```
11131140 ///
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+ ///
11141149 /// [`chunks_exact`]: slice::chunks_exact
11151150 #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
11161151 #[ inline]
11171152 #[ track_caller]
11181153 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+ }
11201157 ArrayChunks :: new ( self )
11211158 }
11221159
@@ -1127,7 +1164,6 @@ impl<T> [T] {
11271164 ///
11281165 /// This may only be called when
11291166 /// - The slice splits exactly into `N`-element chunks (aka `self.len() % N == 0`).
1130- /// - `N != 0`.
11311167 ///
11321168 /// # Examples
11331169 ///
@@ -1147,14 +1183,28 @@ impl<T> [T] {
11471183 ///
11481184 /// // These would be unsound:
11491185 /// // 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
11511186 /// ```
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+ ///
11521198 #[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
11531199 #[ inline]
11541200 #[ must_use]
11551201 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+ }
11561205 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.
11581208 let new_len = unsafe {
11591209 assert_unsafe_precondition ! (
11601210 "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] {
11711221 /// starting at the beginning of the slice,
11721222 /// and a remainder slice with length strictly less than `N`.
11731223 ///
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- ///
11791224 /// # Examples
11801225 ///
11811226 /// ```
@@ -1191,16 +1236,28 @@ impl<T> [T] {
11911236 /// }
11921237 /// assert_eq!(v, &[1, 1, 2, 2, 9]);
11931238 /// ```
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+ ///
11941248 #[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
11951249 #[ inline]
11961250 #[ track_caller]
11971251 #[ must_use]
11981252 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+ }
12001256 let len = self . len ( ) / N ;
12011257 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
12031259 // that the length of the subslice is a multiple of N.
1260+ // `N` cannot be zero because we checked it using compile assert above.
12041261 let array_slice = unsafe { multiple_of_n. as_chunks_unchecked_mut ( ) } ;
12051262 ( array_slice, remainder)
12061263 }
@@ -1209,11 +1266,6 @@ impl<T> [T] {
12091266 /// starting at the end of the slice,
12101267 /// and a remainder slice with length strictly less than `N`.
12111268 ///
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- ///
12171269 /// # Examples
12181270 ///
12191271 /// ```
@@ -1229,16 +1281,28 @@ impl<T> [T] {
12291281 /// }
12301282 /// assert_eq!(v, &[9, 1, 1, 2, 2]);
12311283 /// ```
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+ ///
12321293 #[ unstable( feature = "slice_as_chunks" , issue = "74985" ) ]
12331294 #[ inline]
12341295 #[ track_caller]
12351296 #[ must_use]
12361297 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+ }
12381301 let len = self . len ( ) / N ;
12391302 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
12411304 // that the length of the subslice is a multiple of N.
1305+ // `N` cannot be zero because we checked it using compile assert above.
12421306 let array_slice = unsafe { multiple_of_n. as_chunks_unchecked_mut ( ) } ;
12431307 ( remainder, array_slice)
12441308 }
@@ -1252,11 +1316,6 @@ impl<T> [T] {
12521316 ///
12531317 /// This method is the const generic equivalent of [`chunks_exact_mut`].
12541318 ///
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- ///
12601319 /// # Examples
12611320 ///
12621321 /// ```
@@ -1271,12 +1330,22 @@ impl<T> [T] {
12711330 /// assert_eq!(v, &[1, 1, 2, 2, 0]);
12721331 /// ```
12731332 ///
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+ ///
12741341 /// [`chunks_exact_mut`]: slice::chunks_exact_mut
12751342 #[ unstable( feature = "array_chunks" , issue = "74985" ) ]
12761343 #[ inline]
12771344 #[ track_caller]
12781345 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+ }
12801349 ArrayChunksMut :: new ( self )
12811350 }
12821351
@@ -1287,11 +1356,6 @@ impl<T> [T] {
12871356 ///
12881357 /// If `N` is greater than the size of the slice, it will return no windows.
12891358 ///
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- ///
12951359 /// # Examples
12961360 ///
12971361 /// ```
@@ -1304,12 +1368,22 @@ impl<T> [T] {
13041368 /// assert!(iter.next().is_none());
13051369 /// ```
13061370 ///
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+ ///
13071379 /// [`windows`]: slice::windows
13081380 #[ unstable( feature = "array_windows" , issue = "75027" ) ]
13091381 #[ inline]
13101382 #[ track_caller]
13111383 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+ }
13131387 ArrayWindows :: new ( self )
13141388 }
13151389
0 commit comments