Question on vector of mutable reference into struct

Recently I have encountered a problem when trying to write a function which takes a mutable reference of customized structrure (MatrixFull) and returns a mutable reference. The code is shown below

pub fn get_submatrixfull_mut(&mut self, x:Range<usize>, y:Range<usize>) -> MatrixFull<&mut T> {
    let new_vec = self.get_slice_mut(x.len(), y.len());
    let mat_new = MatrixFull::new([x.len(),y.len], vec![]);
    new_vec.iter().map(|v| mat_new.data.push(v))
    mat_new
}

And the definition of MatrixFull is as below:

#[derive(Clone,Debug,PartialEq)]
pub struct MatrixFull<T:Clone+Display+Send+Sync> {
/// Coloum-major 4-D ERI designed for quantum chemistry calculations specifically.
//pub store_format : ERIFormat,
//pub rank: usize,
pub size : [usize;2],
pub indicing: [usize;2],
pub data : Vec
}
impl <T: Copy + Clone + Display + Send + Sync> MatrixFull {
pub fn new(size: [usize;2], new_default: T) -> MatrixFull {
let mut indicing = [0usize;2];
let mut len = size.iter()
.zip(indicing.iter_mut())
.fold(1usize,|len,(di,ii)| {
*ii = len;
len * di
});
//len *= size[1];
//println!("matrixfull size: {:?},{:?},{:?}",size,len,indicing);
MatrixFull {
size,
indicing,
data: vec![new_default.clone(); len]
}
}
}

However, there is an error saying that

"message": "the trait bound &mut T: Clone is not satisfied\nthe following other types implement trait Clone:
&T
*const T
*mut T
Clone is implemented for &T, but not for &mut T",

Interestingly, if the function returns a vec<&mut T>, there will not be an error.
I wonder why does this error message appear, and how can I fix this error.
Thank you.

Mutable references must be unique, hence they are not Clone. There's nothing you can do about this; it's a fundamental requirement of soundness. (Shared mutability is exactly what Rust is trying to prevent, as it causes memory management errors.)

1 Like

Please read the pinned formatting post.


There were a lot of other problems with your code (maybe in part due to markdown eating <>s, but also missing semicolons and () and other things), so it's hard to give great feedback. You might get better feedback if you can reproduce your problem in the playground.

But as @H2CO3 said, &mut _ can't be Clone (and thus neither can Vec<&mut _>).

2 Likes

Don't put generic constraints on struct definition. Put them on the impl block.

1 Like

One approach to get around &mut's lack of a Clone implementation is to use &Cell<...> instead:

(untested)

pub fn get_submatrixfull_mut(&mut self, x:Range<usize>, y:Range<usize>) -> MatrixFull<&Cell<T>> {
    let new_vec = Cell::from_mut(self.get_slice_mut(x.len(), y.len())).as_slice_of_cells();
    let mat_new = MatrixFull::new([x.len(),y.len], vec![]);
    new_vec.iter().map(|v| mat_new.data.push(v))
    mat_new
}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.