From c615f454b89e5510eca03face32f5df4f76d55ac Mon Sep 17 00:00:00 2001 From: Ebrahim Eldesoky Date: Fri, 19 Jun 2026 13:40:39 +0300 Subject: [PATCH 1/2] Make ArrayViewMut::into_view public and implement From conversion (#1595) - Change ArrayViewMut::into_view visibility to pub - Add From for ArrayView implementation - Add regression tests in tests/views.rs --- src/arraytraits.rs | 11 ++++++++++ src/impl_views/conversions.rs | 7 ++++-- tests/views.rs | 41 +++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) 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..2edc15696 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. + /// + /// Unlike [`Self::view`], this method consumes the mutable view and preserves + /// the original lifetime 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..f36027a99 100644 --- a/tests/views.rs +++ b/tests/views.rs @@ -15,3 +15,44 @@ 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]); +} From da0b686cfb28323a7250d22df4387c8c03abc104 Mon Sep 17 00:00:00 2001 From: Ebrahim Eldesoky Date: Fri, 19 Jun 2026 15:33:37 +0300 Subject: [PATCH 2/2] Fix docs link and format for CI --- src/impl_views/conversions.rs | 4 ++-- tests/views.rs | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/impl_views/conversions.rs b/src/impl_views/conversions.rs index 2edc15696..cfa330e17 100644 --- a/src/impl_views/conversions.rs +++ b/src/impl_views/conversions.rs @@ -275,8 +275,8 @@ where D: Dimension { /// Convert into a read-only view. /// - /// Unlike [`Self::view`], this method consumes the mutable view and preserves - /// the original lifetime of the data. + /// 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 f36027a99..40b867403 100644 --- a/tests/views.rs +++ b/tests/views.rs @@ -33,16 +33,20 @@ fn test_view_conversion() fn test_view_conversion_lifetime() { // Regression test for #1595 - struct Foo<'a> { + struct Foo<'a> + { data: ArrayViewMut2<'a, f32>, } - impl<'a> Foo<'a> { - fn into_shared(self) -> ArrayView2<'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> { + fn into_shared_from(self) -> ArrayView2<'a, f32> + { self.data.into() } }