Is there some unsafe way to take ownership of a contained value in order to mutate it?

410 Views Asked by At

I have a mutable reference to a container, and I want to modify one of its interior values:

struct BigContainer {
    contained: BigUint,
}

fn double(container: &mut BigContainer) {
    container.contained = container.contained * 2_usize;
}

BigUint doesn't implement MulAssign, so we can't just use the *= operator. Consequently, the code as written fails, because Mul takes ownership of the value; we need to temporarily move out of borrowed content. (playground)

We can get around that by initializing a temporary value, and using std::mem::replace: (playground)

fn double(container: &mut BigContainer) {
    let prev_value = mem::replace(&mut container.contained, 0_usize.into());
    container.contained = prev_value * 2_usize;
}

This works, but it's a bit ugly, and we need to create that pointless filler value to temporarily hold the position open for us. What I want is some unsafe method which lets me just override the borrow checker. Unfortunately, the following does not work: (playground)

fn double(container: &mut BigContainer) {
    unsafe {
        container.contained = container.contained * 2_usize;
    }
}

The unsafe block does nothing for us in this case. Is there any way to accomplish this, safe or not, which eliminates the temporary value allocation? If not, is the compiler at least smart enough to skip it?

0

There are 0 best solutions below