Why is pinning a shared reference safe?

"For example, calling Pin::new_unchecked on an &'a mut T is unsafe because while you are able to pin it for the given lifetime 'a, you have no control over whether it is kept pinned once 'a ends, and therefore cannot uphold the guarantee that a value, once pinned, remains pinned until it is dropped:"

use std::mem;
use std::pin::Pin;

fn move_pinned_ref<T>(mut a: T, mut b: T) {
    unsafe {
        let p: Pin<&mut T> = Pin::new_unchecked(&mut a);
        // This should mean the pointee `a` can never move again.
    }
    mem::swap(&mut a, &mut b); // Potential UB down the road ⚠️
    // The address of `a` changed to `b`'s stack slot, so `a` got moved even
    // though we have previously pinned it! We have violated the pinning API contract.
}

This is from rust's official documentation of Pin::new_unchecked https://doc.rust-lang.org/std/pin/struct.Pin.html#method.new_unchecked. So why is calling new_unchecked on shared reference &T safe? I can still move T itself afterwards. For example, in the following code, I can simply change the sample code to using shared reference. Why is this safe?

fn move_pinned<T>(mut var: T, mut b: T) {
    unsafe {
        let p: Pin<&T> = Pin::new_unchecked(&var);
    }
    mem::swap(&mut var, &mut b);
}

There is unsafe there so the code is not safe.

Safe and unsafe refer to safe/unsafe code or functions. Then there is undefined behaviour (UB) which can only occur at runtime. We call safe functions that allow safe code to trigger undefined behaviour unsound. This might seem nitpicky but is important to avoid misunderstandings.

What makes you think that your move_pinned is potentially sound?

2 Likes

It's not - calling new_unchecked is always unsafe, and calling new_unchecked on a reference is potentially unsound whether the reference is exclusive or shared.

The use of &'a mut in the documentation is just because most of the early use cases for Pin require a Pin<&'a mut T>, not a Pin<&'a T>, and thus the doc writer was thinking about &'a mut T.

4 Likes