diff --git a/src/arraytraits.rs b/src/arraytraits.rs index 8b214ac9d..367ae1efa 100644 --- a/src/arraytraits.rs +++ b/src/arraytraits.rs @@ -647,6 +647,17 @@ where } } +/// Implementation of `ArrayView::from(ArrayViewMut)` +impl<'a, A, D> From> for ArrayView<'a, A, D> +where D: Dimension +{ + /// Create a read-only array view from a mutable array view. + fn from(view: ArrayViewMut<'a, A, D>) -> Self + { + view.into_view() + } +} + impl From> for ArcArray where D: Dimension { diff --git a/src/impl_views/conversions.rs b/src/impl_views/conversions.rs index 54d7ed207..cfa330e17 100644 --- a/src/impl_views/conversions.rs +++ b/src/impl_views/conversions.rs @@ -273,8 +273,11 @@ where D: Dimension impl<'a, A, D> ArrayViewMut<'a, A, D> where D: Dimension { - // Convert into a read-only view - pub(crate) fn into_view(self) -> ArrayView<'a, A, D> + /// Convert into a read-only view. + /// + /// This method consumes the mutable view and returns an `ArrayView` that + /// preserves the original lifetime `'a` of the data. + pub fn into_view(self) -> ArrayView<'a, A, D> { unsafe { ArrayView::new(self.parts.ptr, self.parts.dim, self.parts.strides) } } diff --git a/tests/views.rs b/tests/views.rs index 02970b1b7..40b867403 100644 --- a/tests/views.rs +++ b/tests/views.rs @@ -15,3 +15,48 @@ fn cell_view() } assert_eq!(a, answer); } + +#[test] +fn test_view_conversion() +{ + let mut a = Array2::::zeros((4, 4)); + let view_mut = a.view_mut(); + let view = view_mut.into_view(); + assert_eq!(view.shape(), &[4, 4]); + + let view_mut = a.view_mut(); + let view: ArrayView2<'_, f32> = view_mut.into(); + assert_eq!(view.shape(), &[4, 4]); +} + +#[test] +fn test_view_conversion_lifetime() +{ + // Regression test for #1595 + struct Foo<'a> + { + data: ArrayViewMut2<'a, f32>, + } + + impl<'a> Foo<'a> + { + fn into_shared(self) -> ArrayView2<'a, f32> + { + self.data.into_view() + } + + fn into_shared_from(self) -> ArrayView2<'a, f32> + { + self.data.into() + } + } + + let mut a = Array2::::zeros((4, 4)); + let foo = Foo { data: a.view_mut() }; + let shared = foo.into_shared(); + assert_eq!(shared.shape(), &[4, 4]); + + let foo = Foo { data: a.view_mut() }; + let shared = foo.into_shared_from(); + assert_eq!(shared.shape(), &[4, 4]); +}