Skip to content

Commit 61cf7c0

Browse files
jturner314bluss
authored andcommitted
Make slice_collapse panic on NewAxis
1 parent 9614b13 commit 61cf7c0

File tree

4 files changed

+61
-23
lines changed

4 files changed

+61
-23
lines changed

src/impl_methods.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -461,12 +461,15 @@ where
461461

462462
/// Slice the array in place without changing the number of dimensions.
463463
///
464-
/// Note that `NewAxis` elements in `info` are ignored.
465-
///
466464
/// See [*Slicing*](#slicing) for full documentation.
467465
///
468-
/// **Panics** if an index is out of bounds or step size is zero.<br>
469-
/// (**Panics** if `D` is `IxDyn` and `info` does not match the number of array axes.)
466+
/// **Panics** in the following cases:
467+
///
468+
/// - if an index is out of bounds
469+
/// - if a step size is zero
470+
/// - if [`AxisSliceInfo::NewAxis`] is in `info`, e.g. if [`NewAxis`] was
471+
/// used in the [`s!`] macro
472+
/// - if `D` is `IxDyn` and `info` does not match the number of array axes
470473
pub fn slice_collapse<I>(&mut self, info: &I)
471474
where
472475
I: CanSlice<D> + ?Sized,
@@ -487,7 +490,7 @@ where
487490
self.collapse_axis(Axis(axis), i_usize);
488491
axis += 1;
489492
}
490-
AxisSliceInfo::NewAxis => {}
493+
AxisSliceInfo::NewAxis => panic!("`slice_collapse` does not support `NewAxis`."),
491494
});
492495
debug_assert_eq!(axis, self.ndim());
493496
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ pub type Ixs = isize;
498498
/// is selected and the axis is removed; this selects a subview. See
499499
/// [*Subviews*](#subviews) for more information about subviews. If a
500500
/// [`NewAxis`] instance is used, a new axis is inserted. Note that
501-
/// [`.slice_collapse()`] ignores `NewAxis` elements and behaves like
501+
/// [`.slice_collapse()`] panics on `NewAxis` elements and behaves like
502502
/// [`.collapse_axis()`] by preserving the number of dimensions.
503503
///
504504
/// [`.slice()`]: #method.slice

src/slice.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ impl_slicearg!((), NewAxis, Ix0, Ix1);
723723
/// * *slice* `;` *step*: a range constructed from the start and end of a [`Slice`]
724724
/// instance, with new step size *step*, to use for slicing that axis.
725725
/// * *new-axis*: a [`NewAxis`] instance that represents the creation of a new axis.
726+
/// (Except for [`.slice_collapse()`], which panics on [`NewAxis`] elements.)
726727
///
727728
/// [`Slice`]: struct.Slice.html
728729
/// [`NewAxis`]: struct.NewAxis.html
@@ -734,13 +735,14 @@ impl_slicearg!((), NewAxis, Ix0, Ix1);
734735
/// `RangeFull` where `I` is `isize`, `usize`, or `i32`. *step* must be a type
735736
/// that can be converted to `isize` with the `as` keyword.
736737
///
737-
/// For example `s![0..4;2, 6, 1..5, NewAxis]` is a slice of the first axis for
738-
/// 0..4 with step size 2, a subview of the second axis at index 6, a slice of
739-
/// the third axis for 1..5 with default step size 1, and a new axis of length
740-
/// 1 at the end of the shape. The input array must have 3 dimensions. The
741-
/// resulting slice would have shape `[2, 4, 1]` for [`.slice()`],
742-
/// [`.slice_mut()`], and [`.slice_move()`], and shape `[2, 1, 4]` for
743-
/// [`.slice_collapse()`].
738+
/// For example, `s![0..4;2, 6, 1..5, NewAxis]` is a slice of the first axis
739+
/// for 0..4 with step size 2, a subview of the second axis at index 6, a slice
740+
/// of the third axis for 1..5 with default step size 1, and a new axis of
741+
/// length 1 at the end of the shape. The input array must have 3 dimensions.
742+
/// The resulting slice would have shape `[2, 4, 1]` for [`.slice()`],
743+
/// [`.slice_mut()`], and [`.slice_move()`], while [`.slice_collapse()`] would
744+
/// panic. Without the `NewAxis`, i.e. `s![0..4;2, 6, 1..5]`,
745+
/// [`.slice_collapse()`] would result in an array of shape `[2, 1, 4]`.
744746
///
745747
/// [`.slice()`]: struct.ArrayBase.html#method.slice
746748
/// [`.slice_mut()`]: struct.ArrayBase.html#method.slice_mut

tests/array.rs

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ fn test_slice_array_fixed() {
201201
arr.slice(info);
202202
arr.slice_mut(info);
203203
arr.view().slice_move(info);
204-
arr.view().slice_collapse(info);
204+
let info2 = s![1.., 1, ..;2];
205+
arr.view().slice_collapse(info2);
205206
}
206207

207208
#[test]
@@ -211,7 +212,8 @@ fn test_slice_dyninput_array_fixed() {
211212
arr.slice(info);
212213
arr.slice_mut(info);
213214
arr.view().slice_move(info);
214-
arr.view().slice_collapse(info);
215+
let info2 = s![1.., 1, ..;2];
216+
arr.view().slice_collapse(info2);
215217
}
216218

217219
#[test]
@@ -227,7 +229,13 @@ fn test_slice_array_dyn() {
227229
arr.slice(info);
228230
arr.slice_mut(info);
229231
arr.view().slice_move(info);
230-
arr.view().slice_collapse(info);
232+
let info2 = &SliceInfo::<_, Ix3, IxDyn>::try_from([
233+
AxisSliceInfo::from(1..),
234+
AxisSliceInfo::from(1),
235+
AxisSliceInfo::from(..).step_by(2),
236+
])
237+
.unwrap();
238+
arr.view().slice_collapse(info2);
231239
}
232240

233241
#[test]
@@ -243,7 +251,13 @@ fn test_slice_dyninput_array_dyn() {
243251
arr.slice(info);
244252
arr.slice_mut(info);
245253
arr.view().slice_move(info);
246-
arr.view().slice_collapse(info);
254+
let info2 = &SliceInfo::<_, Ix3, IxDyn>::try_from([
255+
AxisSliceInfo::from(1..),
256+
AxisSliceInfo::from(1),
257+
AxisSliceInfo::from(..).step_by(2),
258+
])
259+
.unwrap();
260+
arr.view().slice_collapse(info2);
247261
}
248262

249263
#[test]
@@ -259,7 +273,13 @@ fn test_slice_dyninput_vec_fixed() {
259273
arr.slice(info);
260274
arr.slice_mut(info);
261275
arr.view().slice_move(info);
262-
arr.view().slice_collapse(info);
276+
let info2 = &SliceInfo::<_, Ix3, Ix2>::try_from(vec![
277+
AxisSliceInfo::from(1..),
278+
AxisSliceInfo::from(1),
279+
AxisSliceInfo::from(..).step_by(2),
280+
])
281+
.unwrap();
282+
arr.view().slice_collapse(info2);
263283
}
264284

265285
#[test]
@@ -275,7 +295,13 @@ fn test_slice_dyninput_vec_dyn() {
275295
arr.slice(info);
276296
arr.slice_mut(info);
277297
arr.view().slice_move(info);
278-
arr.view().slice_collapse(info);
298+
let info2 = &SliceInfo::<_, Ix3, IxDyn>::try_from(vec![
299+
AxisSliceInfo::from(1..),
300+
AxisSliceInfo::from(1),
301+
AxisSliceInfo::from(..).step_by(2),
302+
])
303+
.unwrap();
304+
arr.view().slice_collapse(info2);
279305
}
280306

281307
#[test]
@@ -324,35 +350,42 @@ fn test_slice_collapse_with_indices() {
324350

325351
{
326352
let mut vi = arr.view();
327-
vi.slice_collapse(s![NewAxis, 1.., 2, ..;2]);
353+
vi.slice_collapse(s![1.., 2, ..;2]);
328354
assert_eq!(vi.shape(), &[2, 1, 2]);
329355
assert!(vi
330356
.iter()
331357
.zip(arr.slice(s![1.., 2..3, ..;2]).iter())
332358
.all(|(a, b)| a == b));
333359

334360
let mut vi = arr.view();
335-
vi.slice_collapse(s![1, NewAxis, 2, ..;2]);
361+
vi.slice_collapse(s![1, 2, ..;2]);
336362
assert_eq!(vi.shape(), &[1, 1, 2]);
337363
assert!(vi
338364
.iter()
339365
.zip(arr.slice(s![1..2, 2..3, ..;2]).iter())
340366
.all(|(a, b)| a == b));
341367

342368
let mut vi = arr.view();
343-
vi.slice_collapse(s![1, 2, NewAxis, 3]);
369+
vi.slice_collapse(s![1, 2, 3]);
344370
assert_eq!(vi.shape(), &[1, 1, 1]);
345371
assert_eq!(vi, Array3::from_elem((1, 1, 1), arr[(1, 2, 3)]));
346372
}
347373

348374
// Do it to the ArcArray itself
349375
let elem = arr[(1, 2, 3)];
350376
let mut vi = arr;
351-
vi.slice_collapse(s![1, 2, 3, NewAxis]);
377+
vi.slice_collapse(s![1, 2, 3]);
352378
assert_eq!(vi.shape(), &[1, 1, 1]);
353379
assert_eq!(vi, Array3::from_elem((1, 1, 1), elem));
354380
}
355381

382+
#[test]
383+
#[should_panic]
384+
fn test_slice_collapse_with_newaxis() {
385+
let mut arr = Array2::<u8>::zeros((2, 3));
386+
arr.slice_collapse(s![0, 0, NewAxis]);
387+
}
388+
356389
#[test]
357390
fn test_multislice() {
358391
macro_rules! do_test {

0 commit comments

Comments
 (0)