#Cannot move out of dereference of 'Mut<...>'

22 messages · Page 1 of 1 (latest)

grave citrus
#

Beginner in Rust and Bevy.

Here are the relevant components:

#[derive(Component)]
struct Brake {
    driver_valve: BrakeDriverValve,
    system: BrakeSystem,
}

#[derive(Component)]
struct BrakeDriverValve {
    position: BrakeDriver,
}

enum BrakeDriver {
    Release,
    Running,
    Lap,
    Application,
}

Here is part of my query function:

for (mut car_transform, mut brake) in query.iter_mut() {
  /*function call here*/ brake.driver_valve.position /*finish argument list*/
}

Any guidance would be very much appreciated!

#

Oh, I forgot to add the rest of the error message

#
cannot move out of dereference of `Mut<'_, Brake>`
move occurs because value has type `BrakeDriver`, which does not implement the `Copy` trait
#

This is at brake.driver_valve.position

main bolt
#

I'd recommend reading CH 4 of the Rust book to get a better understanding of data ownership: https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html.

In this case the Brake data structure owns the driver_valve field. If you want to pass that field as an argument to the function you need to pass a reference to it or copy the underlying memory.

EDIT: I see now it's actually BrakeDriverValve owning the position field causing the issue. But the same holds.

#

Basically in Rust you cannot pass an individual field of a struct to another function directly if it owns that field (i.e. not a &). Passing it directly would mean the new function would own that field and thus it would be "moved out" of the data structure. Which isn't allowed, the data structure in this case needs to retain ownership of that field.

#

You can add

#[derive(Copy)]
enum BrakeDriver {

This would mean that the position field would become a data type that is pass by value (i.e. it gets copied when passed to a function).

#

In this case since BrakeDriver is a simple enum, it probably makes sense to have it be copied there.

grave citrus
#

Ok, this is quite a lot of new stuff for me! Thank you for the explainer (:

#

This would still apply if I passed brake.driver_valve only, right?

#

Because that is still a field of a struct which I am copying out

main bolt
#

Correct.

grave citrus
main bolt
#

You can pass a reference.

#

&brake.driver_valve.position

grave citrus
#

Would that work?

main bolt
#

And then you'd need to modify your function to take a reference to BrakeDriver (i.e. foo: &BrakeDriver) instead of foo: BrakeDriver)

#

You can do that or derive(Copy) on your BrakeDriver enum.

#

In the case of simple enums I prefer to derive Copy since passing by value doesn't have much downsides.

grave citrus
#

Anyway, thank you for the pointers, this is very helpful (:

main bolt