Suppose I have two Pin<Box<T>>
s, e.g. I got them from Box::pin(struct_of_type_T)
, a Box
owns the pointer to the underlying value of type T
, a Pin
ensures that the value (of type T
) to which the pointer is pointing to is never moved.
Can I swap the two pointers within the 'Pinned-box'?
pinned_box_1 pinned_box_2
|-------------| |-------------|
| pointer_one |<--swap them--?>| pointer_two |
|-------------| |-------------|
| |
V V
struct_of_type_T_one struct_of_type_T_two
|-------------| |-------------|
| value_one | | value_two |
|-------------| |-------------|
fixed_addr fixed_addr
If yes, how do I swap them? Will std::mem::swap
work in this case?
The answer to the body of your question is yes, you can, you don't even need std::mem::swap
:
fn main() {
let mut pointer_one = Box::pin(99);
let mut pointer_two = Box::pin(88);
println!("pointer_one: {0:p}, {0}", pointer_one);
println!("pointer_two: {0:p}, {0}", pointer_two);
std::mem::swap(&mut pointer_one, &mut pointer_two);
// (pointer_one, pointer_two) = (pointer_two, pointer_one); //also works
println!("\nafter swap\n");
println!("pointer_one: {0:p}, {0}", pointer_one);
println!("pointer_two: {0:p}, {0}", pointer_two);
}
output:
pointer_one: 0x558a90ebb9d0, 99
pointer_two: 0x558a90ebb9f0, 88
after swap
pointer_one: 0x558a90ebb9f0, 88
pointer_two: 0x558a90ebb9d0, 99
This is possible because Pin
only makes guarantees about the pointee, not the pointer itself, like any other value the pointer remains movable.
The answer to the title of your question is no, it's not possible to swap two values behind pinned pointers, that's exactly what Pin
was made to prevent, the moving of the values.
There is one exception, if the type behind the pointer implemnts Unpin
that signals it's save to move values of that type and Pin<Ptr<T>>
will implement DerefMut
allowing a swap.