0

Yes I have read the docs, three times.

I have looked at: Cannot move out of borrowed content in Rust and Cannot move out of borrowed content. Neither of these answer my question or help me get a better understanding of what's going on here.

Consider the following code snippet:

pub trait Scene {
    fn on_start(&mut self) {}
    fn update(&mut self) {}
    fn stop(&mut self) {}
    fn is_active(&self) -> bool { return false; }
}

pub struct SceneManager {
    scenes: Vec<Box<Scene>>
}

impl SceneManager {
    fn new<T>(mut scene: T) -> SceneManager where T: Scene + 'static {
        scene.on_start();

        SceneManager {
            scenes: vec![Box::new(scene)]
        }
    }

    fn update_children(&mut self) {
        for mut scene in &mut self.scenes {
            scene.update();
        }
    }
    ...

    fn get_children(&self) -> Vec<Box<Scene>> {
        return self.scenes
    }

    ...
}

#[cfg(test)]
mod tests {
    use super::*;

    struct Sample {
        running: bool
    }

    impl Scene for Sample {
        fn update(&mut self) {
            if self.running {
                self.stop()
            }
        }

        fn stop(&mut self) {
            self.running = false;
        }

        fn is_active(&self) -> bool { self.running }
    }

    ...

    #[test]
    fn test_no_scene_is_running() {
        let mut scene_manager = SceneManager::new(Sample{running: true});
        scene_manager.update_children();
        let children = scene_manager.get_children();
        for mut scenes in children {
            assert!(!scene.is_active());
        }
    }
}

Issue:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:12:9
   |
12 |         self.scenes
   |         ^^^^ cannot move out of borrowed content

We have seen it a million times. Most of the answers say to use &self instead of self. Well that's what I am doing here. even &mut self doesn't work, although I am not mutating anything here so no need for that.

Please enlighten me and point me to docs that explain how I cannot do this.

Shepmaster
  • 274,917
  • 47
  • 731
  • 969
TheWebs
  • 10,087
  • 21
  • 77
  • 164
  • 2
    Why should this not be a duplicate of https://stackoverflow.com/q/28258548/155423 ? – Shepmaster Aug 10 '17 at 17:43
  • 2
    Ownership matters a lot in Rust. Do you want `get_children` to return _copies_ of the scenes, or _references_ to the scenes? Otherwise you're transferring ownership, which causes the issue you are seeing. This is explained in the question linked above. – loganfsmyth Aug 10 '17 at 17:51
  • I want a reference to the scenes in a mutable way, so I can loop over it and call the scene methods (which may mutate data from the struct the scene implements, like in this case, update method will set `running` to false if running. – TheWebs Aug 10 '17 at 17:53
  • 1
    `Vec>` explicitly says "a vector that owns a bunch of `Scene` objects. If you want references, your type should include references, like `&mut [Box]` or something. This was already explained in https://stackoverflow.com/questions/40075031/cannot-move-out-of-borrowed-content-in-rust – loganfsmyth Aug 10 '17 at 17:59
  • cool story bro. Shits fixed – TheWebs Aug 10 '17 at 18:00
  • Dang dude, if you want help getting frustrated with people isn't the way to do it... – loganfsmyth Aug 10 '17 at 18:05
  • As a general observation, looking at your previous questions, can I suggest in the nicest way possible that you might benefit from fiddling with simpler Rust programs prior to jumping into game development with Rust? Rust is a different beast compared to most and as you're now finding, things you expect to work in another language you're more comfortable in don't work in Rust and poking and prodding at it constant gets you nowhere. Its clearly making you frustrated (which, it really shouldn't). A more thorough understanding of the language itself would benefit here and stop the frustrations. – Simon Whitehead Aug 11 '17 at 00:49
  • When I say "a more thorough understanding of the language" I don't mean spending 2 hours reading the documentation before jumping back into Rust game dev... I mean reading the documentation, trying a little snippet to get an understanding, changing it, breaking it, etc. Smaller snippets help in understanding the issues you're facing and once you can solve the issues in smaller samples the bigger ones will begin to make more sense. Just trying to give some advice, anyway. Do with it what you will. Good luck! – Simon Whitehead Aug 11 '17 at 00:50

1 Answers1

1

Your fn get_children(&self) is equivalent to

fn get_children(&self) -> Vec<Box<Scene>> {
    return self.scenes;
}

You call the function like

let children = scene_manager.get_children();

This effectively moves the self.scenes variable into children;

You called the function get_children with argument (&self), so the variable scene_manager is borrowed into the function, and later you are trying to return (or move) a value from inside the struct, which is what the compiler complains about.

Malice
  • 1,329
  • 15
  • 28
  • 4
    Why is this accepted if it directly contradicts your comment saying `I want a reference to the scenes in a mutable way`? – loganfsmyth Aug 10 '17 at 18:03