Is boxing &mut self into itself possible "in one line"?

Having something like this:

enum Bar {
    Single,
    Multi(Box<Bar>, Box<Bar>),
}


impl std::ops::AddAssign for Bar {
    fn add_assign(&mut self, rhs: Bar) {
        *self = Bar::Multi(Box::new(*self), Box::new(rhs)); // <- error E0507
        // "workaround"
        // let current = std::mem::replace(self, Bar::Single);
        // *self = Bar::Multi(Box::new(current), Box::new(rhs)); 
    }
}

fn main() {
    let mut bar = Bar::Single;

    bar += Bar::Single;
}

Playground Link

I currently have the workaround in my code, which does something similar. I tried to think how to do this with std::mem::replace() or std::mem::take() but couldn't figure it out.

So my question is, is possible to do something similar to the line that produces the error?

No, using mem::replace (or mem::take, in case you add a Default implementation) is necessary, and I wouldn't even consider it a "workaround". You can still make it into a single expression though.

impl std::ops::AddAssign for Bar {
    fn add_assign(&mut self, rhs: Bar) {
        *self = Bar::Multi(
            Box::new(std::mem::replace(self, Bar::Single)),
            Box::new(rhs),
        );
    }
}

For structs that don't have a cheaply available dummy value, you could resort to using the API provided by the crate replace_with - Rust instead.

Didn't know about that crate, I'll look into it. Thanks!

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.