Borrowing/Moving issue


#1

Hi,

I am having trouble getting the following code to compile. Thanks to the helpful error message I believe I understand why this doesn’t work, however after trying a few different things I haven’t found a way to achieve what I need to do.

This is a contrived version of what my program needs to do. Basically I need to keep a reference to the currrent enum value then change it on self and return the original value.

enum MyEnum {
    A,
    B
}

struct MyStruct {
    current_enum: MyEnum
}

impl MyStruct {
    fn next_enum(&mut self) {
        self.current_enum = MyEnum::B;
    }
    
    fn what_is_it(&mut self) -> MyEnum {
        let current = self.current_enum;
        self.next_enum();
        current
    }
}

error message for reference

test.rs:16:23: 16:27 error: cannot move out of borrowed content [E0507]
test.rs:16         let current = self.current_enum;
                                 ^~~~
test.rs:16:23: 16:27 help: run `rustc --explain E0507` to see a detailed explanation
test.rs:16:13: 16:20 note: attempting to move value to here
test.rs:16         let current = self.current_enum;
                       ^~~~~~~
test.rs:16:13: 16:20 help: to prevent the move, use `ref current` or `ref mut current` to capture value by reference

Also to note I have tried following the advise provided in the error messages, however I end up in a loop of errors that eventually brings me back to where I started.

Thanks in advance


#2

The simplest solution would be to add

#[Clone, Copy]
enum MyEnum {
    A,
    B,
}

If your enum is indeed copy. If it is not, I would try something like this:

impl MyStruct {
    fn calculate_next_enum(&self) -> MyEnum { MyEnum::B }
    
    fn what_is_it(&mut self) -> MyEnum {
        let mut result = self.calculate_current_enum();
        ::std::mem::swap(&mut result, &mut self.current_enum);
        result
    }
}

#3

Ah yes, sorry I should have mentioned that I can’t use copy in my actual program. However the second approach works great.

Many thanks!