From a70bf19769224a2db435773a44005782d4eaec6b Mon Sep 17 00:00:00 2001 From: Jim Turner Date: Sun, 19 Dec 2021 19:22:14 -0500 Subject: [PATCH] Fix Miri failure with -Zmiri-tag-raw-pointers Before this commit, running `MIRIFLAGS="-Zmiri-tag-raw-pointers" cargo miri test test_map_axis` caused Miri to report undefined behavior in the `test_map_axis` test. This commit fixes the underlying issue. Basically, Miri doesn't like us using a reference to an element to access other elements. Here's some sample code to illustrate the issue: ```rust let a: Vec = vec![5, 6]; let first_elt: &i32 = &a[0]; let ptr: *const i32 = first_elt as *const i32; // Okay: the data is contained in the data referenced by `first_elt`. let a0 = unsafe { &*ptr.offset(0) }; assert_eq!(*a0, 5); // Not okay: the data is not contained in the data referenced by `first_elt`. let a1 = unsafe { &*ptr.offset(1) }; assert_eq!(*a1, 6); ``` Before this commit, we were using `self.index_axis(axis, 0).map(|first_elt| ...)` to create views of the lanes, from references to the first elements in the lanes. Accessing elements within those views (other than the first element) led to the Miri error, since the view's pointer was derived from a reference to a single element. Thanks to @5225225 for reporting the issue. (This commit fixes #1137.) --- src/impl_methods.rs | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/impl_methods.rs b/src/impl_methods.rs index 19249f9e7..9186cd762 100644 --- a/src/impl_methods.rs +++ b/src/impl_methods.rs @@ -2752,17 +2752,11 @@ where A: 'a, S: Data, { - let view_len = self.len_of(axis); - let view_stride = self.strides.axis(axis); - if view_len == 0 { + if self.len_of(axis) == 0 { let new_dim = self.dim.remove_axis(axis); Array::from_shape_simple_fn(new_dim, move || mapping(ArrayView::from(&[]))) } else { - // use the 0th subview as a map to each 1d array view extended from - // the 0th element. - self.index_axis(axis, 0).map(|first_elt| unsafe { - mapping(ArrayView::new_(first_elt, Ix1(view_len), Ix1(view_stride))) - }) + Zip::from(self.lanes(axis)).map_collect(mapping) } } @@ -2783,21 +2777,11 @@ where A: 'a, S: DataMut, { - let view_len = self.len_of(axis); - let view_stride = self.strides.axis(axis); - if view_len == 0 { + if self.len_of(axis) == 0 { let new_dim = self.dim.remove_axis(axis); Array::from_shape_simple_fn(new_dim, move || mapping(ArrayViewMut::from(&mut []))) } else { - // use the 0th subview as a map to each 1d array view extended from - // the 0th element. - self.index_axis_mut(axis, 0).map_mut(|first_elt| unsafe { - mapping(ArrayViewMut::new_( - first_elt, - Ix1(view_len), - Ix1(view_stride), - )) - }) + Zip::from(self.lanes_mut(axis)).map_collect(mapping) } }