0

I want to learn the ownership model of Rust. In the example below I want to spawn a NonCopy object child from the existing NonCopy object eva and save them in the same vector population.

#[derive(Debug, PartialEq, Hash)]
pub struct NonCopy<'a> {
    name: String,
    parent: Option<&'a NonCopy<'a>>,
}

impl<'a> NonCopy<'a> {
    pub fn new(name: String, parent: Option<&'a NonCopy<'a>>) -> Self { // we create a method to instantiate `NonCopy`
        NonCopy { name: name, parent: parent }
    }

    pub fn say_name(&self) -> String {
        format!("{:}", self.name)
    }
}

pub fn spawn<'a>(parent: &'a NonCopy, name: String) -> NonCopy<'a> {
    NonCopy::new(name, Some(parent))
}

fn main() {
    let eva = NonCopy::new(String::from("Eva"), None);
    let child = spawn(&eva, String::from("Son"));
    let mut population = vec![child];
    population.push(eva);
}

But when I push eva to the vector object population I get following error message:

   Compiling playground v0.1.0 (/home/holger/git/Rust/playground)
error[E0505]: cannot move out of `eva` because it is borrowed
  --> src/main.rs:25:21
   |
23 |     let child = spawn(&eva, String::from("Son"));
   |                       ---- borrow of `eva` occurs here
24 |     let mut population = vec![child];
25 |     population.push(eva);
   |                ---- ^^^ move out of `eva` occurs here
   |                |
   |                borrow later used by call

error: aborting due to previous error

For more information about this error, try `rustc --explain E0505`.
error: could not compile `playground`.

I would like to ask why it is not possible to push eva to the same vector as its spawned child child.

  • eva is borrowd to the function spawn. According to Rust By Example the borrow should be dropped after the end of spawn. Why isn't it dropped?
  • Is it because the result of spawn is still alive after the end of spawn?
  • Is this behaviour related to its non Copy type?
  • How can eva and child be collected in the same Vec object?
Holger
  • 2,125
  • 2
  • 19
  • 30
  • I changed to `let mut population ` and edited the question, but my real problem still occurs. – Holger Sep 01 '20 at 21:16
  • I believe your error is caused by the reference `child` holds to `eva`. Because `child` keeps that reference alive ownership of `eva` cannot be passed to the vector. – elliptic_hyperboloid Sep 01 '20 at 21:21
  • @elliptic_hyperboloid That does not seem to be the case. Even if you change `spawn` to not use the borrowed value, the error still persists. ([Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ef99635be316254fa47a5e84f6bc6e8c)) I think it is more likely that it has to do with the lifetimes, but I don't know enough about it to say for sure. – Herohtar Sep 01 '20 at 21:37
  • I don't think this is a duplicate of the linked question, as the stated error occurs even when the structs have *no* references in them (as shown in the playground linked in my previous comment). – Herohtar Sep 02 '20 at 01:57
  • @Herohtar The lifetime of the returned object has to be different in your playground example. I have created a modified working version ([Playground mod](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=22c8f2f2c37b2c8657115fb1710790a9)). – Holger Feb 09 '23 at 11:10

0 Answers0