diff --git a/src/dimension/mod.rs b/src/dimension/mod.rs index 2ae851d1c..601f0dc43 100644 --- a/src/dimension/mod.rs +++ b/src/dimension/mod.rs @@ -55,7 +55,7 @@ pub fn stride_offset(n: Ix, stride: Ix) -> isize /// There is overlap if, when iterating through the dimensions in order of /// increasing stride, the current stride is less than or equal to the maximum /// possible offset along the preceding axes. (Axes of length ≤1 are ignored.) -pub fn dim_stride_overlap(dim: &D, strides: &D) -> bool +pub(crate) fn dim_stride_overlap(dim: &D, strides: &D) -> bool { let order = strides._fastest_varying_stride_order(); let mut sum_prev_offsets = 0; @@ -255,8 +255,6 @@ where D: Dimension /// allocation. (In other words, the pointer to the first element of the array /// must be computed using `offset_from_low_addr_ptr_to_logical_ptr` so that /// negative strides are correctly handled.) -/// -/// Note, condition (4) is guaranteed to be checked last pub(crate) fn can_index_slice( data: &[A], dim: &D, strides: &D, mode: CanIndexCheckMode, ) -> Result<(), ShapeError> diff --git a/src/impl_raw_views.rs b/src/impl_raw_views.rs index fca5e7de7..5132b1158 100644 --- a/src/impl_raw_views.rs +++ b/src/impl_raw_views.rs @@ -294,6 +294,8 @@ where D: Dimension if let Strides::Custom(strides) = &shape.strides { dimension::strides_non_negative(strides).unwrap(); dimension::max_abs_offset_check_overflow::(&dim, strides).unwrap(); + assert!(!dimension::dim_stride_overlap(&dim, strides), + "The strides must not allow any element to be referenced by two different indices"); } else { dimension::size_of_shape_checked(&dim).unwrap(); } diff --git a/tests/array.rs b/tests/array.rs index 4de22794c..696904dab 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -2281,6 +2281,29 @@ fn test_raw_view_mut_from_shape_ptr_deny_neg_strides() let _view = unsafe { RawArrayViewMut::from_shape_ptr((2, 3).strides((-3isize as usize, 1)), data.as_mut_ptr()) }; } +#[test] +fn test_raw_view_from_shape_allow_overlap() +{ + let data = [0, 1, 2]; + let view; + unsafe { + let raw_view = RawArrayView::from_shape_ptr((2, 3).strides((0, 1)), data.as_ptr()); + view = raw_view.deref_into_view(); + } + assert_eq!(view, aview2(&[data, data])); +} + +#[should_panic(expected = "strides must not allow any element")] +#[cfg(debug_assertions)] +#[test] +fn test_raw_view_mut_from_shape_deny_overlap() +{ + let mut data = [0, 1, 2]; + unsafe { + RawArrayViewMut::from_shape_ptr((2, 3).strides((0, 1)), data.as_mut_ptr()); + } +} + #[test] fn test_default() {