How does this wrong `pin` example work in the docs?

During reading of pinning
I was confused about this example and how it works:

fn main() {
   let mut test1 = Test::new("test1");
   let mut test1_pin = unsafe { Pin::new_unchecked(&mut test1) }; /// Accidentially not shadowed variable `test1`.
   Test::init(test1_pin.as_mut());

   drop(test1_pin); /// asccidentially dropped the wrapper type `Pin<Test>`.
   println!(r#"test1.b points to "test1": {:?}..."#, test1.b);

   let mut test2 = Test::new("test2");
   mem::swap(&mut test1, &mut test2);
   println!("... and now it points nowhere: {:?}", test1.b);
}

I had the following questions which I could not answer:

  • I assumed let mut test1_pin = creates this Pin<Test> wrapper object.
  • I assumed test1_pin.drop() will not modify the initial test1 object.
  • I assumed the last print would give the same result as in the first example where the swap did not work, but it gives 0.
  1. Why is the pointer to test1.b suddenly different to the example: given before in the documentation. Or differently asked, who made that pointer 0? Was it the fact that test1_pin got created and directly after droped?

The "correct" example calls Test::init on both test1 and test2. The example illustrating incorrect code never calls Test::init on test2 - that is why it still has a null pointer which gets mem::swap-ped into test1.

1 Like