How to solve 'cannot move out of a shared reference'?

The following code:

#![allow(dead_code)]

#[derive(Debug, Clone)]
pub struct SmallFiles {
    pub entries: Vec<u8>,
}

#[derive(Debug, Clone)]
pub struct Block {
    pub pos: u64,
    pub size: usize,
}

#[derive(Debug, Clone)]
pub struct BigFile {
    pub blocks: Vec<Block>,
}

#[derive(Debug, Clone)]
pub enum TocEntry {
    SmallFiles(SmallFiles),
    BigFile(BigFile),
}

#[derive(Debug, Clone)]
pub struct Toc {
    pub entries: Vec<TocEntry>,
}

fn main() {
    let mut toc = Toc { entries: Vec::new() };
    let big_file = BigFile { blocks: Vec::new() };
    toc.entries.push(TocEntry::BigFile(big_file));
    let block = Block { pos: 0, size: 0 };
    match &toc.entries[0] {
        TocEntry::BigFile(mut e) => e.blocks.push(block),
        _ => {}
    }
}

fails to compile with error:

Compiling playground v0.0.1 (/playground)
error[E0507]: cannot move out of a shared reference
  --> src/main.rs:35:11
   |
35 |     match &toc.entries[0] {
   |           ^^^^^^^^^^^^^^^
36 |         TocEntry::BigFile(mut e) => e.blocks.push(block),
   |                           -----
   |                           |
   |                           data moved here
   |                           move occurs because `e` has type `BigFile`, which does not implement the `Copy` trait

error: aborting due to previous error

I've tried it with "ref mut" in the catch clause and also tried RefCell. But I haven't found a solution which compiles. How can I solve the above issue?

Taking a mutable reference and removing the mut works:

    match &mut toc.entries[0] {
        TocEntry::BigFile(e) => e.blocks.push(block),
        _ => {}
    }

To elaborate on why this works, in your above example mut e causes Rust to attempt to move the data in the BigFile into a mutable variable called e. Just writing e alone tells Rust to borrow it instead. You also need to take a mutable reference to the content at the index instead of a shared one so that you can mutate it.

Thank you very much for the quick fix! It solved my issue.

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.