PREFACE: What you want to do, is definitely possible. However it's hard. Really hard.
Luckily, I'll only show how to do the easy part.
If you look at how split_at_mut is implemented, you can notice it requires you to create a parallel structure that mimics return value of quadrants_mut (i.e. SliceMut):
pub struct SliceMut<'a, T: 'a> { matrix: &'a mut Matrix<T>, start: (usize, usize), end: (usize, usize), } #[repr(C)] struct MatrixRaw<T> { data: *const Matrix<T>, start: (usize, usize), end: (usize, usize), } Note, the similarity between these two structures, if. If at any point they diverge, your mem::transmute will either stop working, or your safe code will experience segfaults.
Then we create a method that transmutes MatrixRaw into SliceMut.
#[inline] pub unsafe fn from_raw_mat_mut<'a, T>( p: *mut Matrix<T>, start: (usize, usize), end: (usize, usize), ) -> SliceMut<'a, T> { mem::transmute(MatrixRaw { data: p, start: start, end: end, }) } As a last step, we add unsafean unsafe block to quadrant_mut:
unsafe { let a = from_raw_mat_mut(matrix, (0, 0), (mid_rows, mid_cols)); let b = from_raw_mat_mut(matrix, (0, mid_rows), (mid_cols, cols)); let c = from_raw_mat_mut(matrix, (mid_rows, rows), (0, mid_cols)); let d = from_raw_mat_mut(matrix, (mid_rows, rows), (mid_cols, cols)); (a, b, c, d) } HARD PART: Here comes the hard part - making sure your methods, and iterators, don't accidentally invalidate your data and invariants. This is extremely hard to achieve in Matrixthe Matrix case.
Why? Well, because there isn't a nice way to say to your data, don't"don't touch these partsparts" like you can with an array. With an array, you just offset your data and you're pretty much good to go. But a MatrixMatrix? It's not impossible, but I suspect I don't know of a way that doesn't introduce performance penalties.