Hi All.
I've run into a small problem. I have a Vec
I want to interpret as a matrix, but I can't instantiate the Vec
as a matrix in the library I'm using because I still need to be able to add more data to it. Thus, I'm temporarily construction a slice of the matrix using the raw pointer. Is this safe, or actually unsafe?
fn do_things<'a>(&'a mut self) {
unsafe {
// slightly risky way to view self.dat as a matrix
// get a mut ref to dat
// really for some 'b: 'a
let dat = &mut self.dat;
// This should have lifetime 'c: 'b, but we can't express that here
// (NB: at least, I think I can't? If there's a way to do this, that would be very handy.)
let mut m : MatrixSliceMut<'_, f64> = {
MatrixSliceMut::from_raw_parts(
eqns.as_mut_ptr(),
self.nrows(),
self.ncols(),
self.ncols(),
)
};
//
// ... do stuff with `m` ...
//
// ensure dat is used last, so the borrow checker warns us if we try to use `self.dat`.
// Should be compiled to a nop.
{ dat; () }
}
}
Ideally, I'd have some way to name fresh lifetimes 'c
and 'b
such that 'c <= 'b <= 'a
, which would ensure that the slice does not outlive the borrow of the field. But I don't know how to do that, if it's possible. (At least, not without spinning it off into its own function.) Thus I'm worried that the compiler might do something unexpected (like an optimisation) because it doesn't infer a relationship between dat
and m
.
Thanks!
P.S.
The MatrixSliceMut
is as follows
pub struct MatrixSliceMut<'a, T: 'a> {
ptr: *mut T,
rows: usize,
cols: usize,
row_stride: usize,
marker: PhantomData<&'a mut T>,
}
The library I'm using is rulinalg, for reference. But hopefully there's enough detail here that you don't have to dive in to the implementation.