I feel confused reading the Pin chapter in Futures Explained in 200 Lines of Rust.
I understand that moving a value breaks self-referential structs:
The memory location of the struct changed and the self reference pointer will fail to work.
With mem::swap, there is no memory relocation of the struct, only the pointer changed:
#[derive(Debug)]
struct Test {
a: String,
b: *const String,
}
The memory location of the struct has not changed.
Another example:
#[derive(Debug)]
struct A {
a: String,
b: String,
}
fn main() {
let mut v1 = A {
a: String::from("a"),
b: String::from("a"),
};
let mut v2 = A {
a: String::from("b"),
b: String::from("b"),
};
println!("v1: {:p} - {:?}", &v1, &v1);
println!("v1 ab:{:p} - {:p}", &v1.a, &v1.b);
println!("v1 ab ptr :{:p} - {:p}", v1.a.as_ptr(), v1.b.as_ptr());
println!("v2: {:p} - {:?}", &v2, &v2);
println!("v2 ab:{:p} - {:p}", &v2.a, &v2.b);
println!("v2 ab ptr :{:p} - {:p}", v2.a.as_ptr(), v2.b.as_ptr());
std::mem::swap(&mut v1, &mut v2);
println!("================");
println!("v1: {:p} - {:?}", &v1, &v1);
println!("v1 ab:{:p} - {:p}", &v1.a, &v1.b);
println!("v1 ab ptr :{:p} - {:p}", v1.a.as_ptr(), v1.b.as_ptr());
println!("v2: {:p} - {:?}", &v2, &v2);
println!("v2 ab:{:p} - {:p}", &v2.a, &v2.b);
println!("v2 ab ptr :{:p} - {:p}", v2.a.as_ptr(), v2.b.as_ptr());
}
The output is:
v1: 0x7ffe13256de0 - A { a: "a", b: "a" }
v1 ab:0x7ffe13256de0 - 0x7ffe13256df8
v1 ab ptr :0x5640172c0b40 - 0x5640172c0b60
v2: 0x7ffe13256e40 - A { a: "b", b: "b" }
v2 ab:0x7ffe13256e40 - 0x7ffe13256e58
v2 ab ptr :0x5640172c0b80 - 0x5640172c0ba0
================
v1: 0x7ffe13256de0 - A { a: "b", b: "b" }
v1 ab:0x7ffe13256de0 - 0x7ffe13256df8
v1 ab ptr :0x5640172c0b80 - 0x5640172c0ba0
v2: 0x7ffe13256e40 - A { a: "a", b: "a" }
v2 ab:0x7ffe13256e40 - 0x7ffe13256e58
v2 ab ptr :0x5640172c0b40 - 0x5640172c0b60
The memory location of v1 v2 stays the same, only the String pointer, the value of a b has swapped.
From the Pin doc:
It is sometimes useful to have objects that are guaranteed not to move, in the sense that their placement in memory does not change, and can thus be relied upon
But swap does not seem to change the memory location. Have I missed some concepts of movement?
Update
I misunderstood the meaning of "move". It's about the value and two pictures are the same thing. Before, I thought that if Test moved, then the address (0x1001) would change, but the address is the variable on the stack, not the value itself.

