Skip to content

ArrayViewMut::into_view() should be public #1595

Closed

Description

@jiawen

There is no public API to convert an owned ArrayViewMut<'a, T, D> to ArrayView<'a, T, D> while preserving the original lifetime 'a. The method into_view() exists internally but is pub(crate).

ArrayViewMut has a .view() method, but it cannot be used here because its signature borrows self. A simplified example of my use case where I have an ArrayViewMut inside a struct:

use ndarray::{ArrayView2, ArrayViewMut2};

struct Foo<'a> {
    data: ArrayViewMut2<'a, f32>,
}

impl<'a> Foo<'a> {
    /// Downgrade to a shared view. This fails to compile.
    fn into_shared(self) -> ArrayView2<'a, f32> {
        self.data.view() // error[E0515]: returns value referencing local `self.data`
    }
}

The compiler complains:

error[E0515]: cannot return value referencing local data `self.data`
  --> src/main.rs:10:9
   |
10 |         self.data.view()
   |         ^^^^^^^^^------
   |         |        |
   |         |        `self.data` is borrowed here
   |         returns a value referencing data owned by the current function

The data pointed to by self.data is valid for 'a, but .view() can only express "valid for the duration of the &self.data borrow", which expires when self is dropped at the end of into_shared. The internal ArrayViewMut::into_view(self) -> ArrayView<'a, A, D> handles this correctly but is pub(crate).

I can work around this with unsafe { std::mem::transmute(...) } as a workaround which is valid but gross.

Request

Make into_view(self) -> ArrayView<'a, A, D> public, or add a From<ArrayViewMut<'a, A, D>> for ArrayView<'a, A, D> impl.

Activity

  1. cschanhniem commented on Jun 19, 2026

    @cschanhniem

    Confirmed on master — src/impl_views/conversions.rs line:

    // Convert into a read-only view
    pub(crate) fn into_view(self) -> ArrayView<'a, A, D>
    {
        unsafe { ArrayView::new(self.parts.ptr, self.parts.dim, self.parts.strides) }
    }

    The fix is a one-line change: make it pub instead of pub(crate). The method is already well-exercised internally — it's used by into_outer_iter, into_axis_iter, into_axis_chunks_iter, into_indexed_iter, and the various into_*_mut methods all chain through it. This gives confidence it won't break anything.

    An alternative (or addition) would be a From impl:

    impl<'a, A, D> From<ArrayViewMut<'a, A, D>> for ArrayView<'a, A, D>
    where D: Dimension
    {
        fn from(view: ArrayViewMut<'a, A, D>) -> Self {
            view.into_view()
        }
    }

    That would let users write let shared: ArrayView<'_, _> = mut_view.into(); directly. Happy to submit a PR with either approach (or both).

  2. jiawen commented on Jun 19, 2026

    @jiawen
    Author

    Amazing, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions