Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If a Pin is changed to point to a different location, what happens? #519

Open
theemathas opened this issue Jul 31, 2024 · 3 comments
Open

Comments

@theemathas
Copy link

theemathas commented Jul 31, 2024

In Pin<Ptr<T>>, the documentation is unclear on what the pinning guarantee is, if the pointer were to be changed to point to a different T. This can happen in at least three different ways, depending on how you count.

  1. The Ptr can implement Deref and/or DerefMut in such a way that it doesn't return the same reference. That is, calling .deref() or .deref_mut() on the same Ptr twice returns two different references.
  2. Someone can transmute a &mut Pin<Ptr<T>> into &mut Ptr<T>, then modify or replace the Ptr so that it points to a different T. (Note that this is possible even with well-behaved pointers such as Pin<&mut T>.)
  3. The Ptr might allow external code to (possibly unsafely) modify where the pointer is pointing to, without going through the pointer directly. (For example, Ptr<T> might contain a Rc<UnsafeCell<Box<T>>>.)

Is changing what the pointer points to unsound? And if it is sound, what memory locations are considered to be pinned, and when?

@Diggsey
Copy link

Diggsey commented Jul 31, 2024

My understanding is that pinning is a property of a place (ie. the target of the pointer), so there are no constraints on what you can do with the pointer itself.

A pointer that dereferences to different places would be confusing but sound.

And if it is sound, what memory locations are considered to be pinned, and when?

Every target of the pointer which is observed to be pinned.

@theemathas
Copy link
Author

When does the no-moving guarantee start though? The first time the deref() was called and observed to be that address? Or when the Pin was first constructed?

@RalfJung
Copy link
Member

RalfJung commented Aug 1, 2024

It's a safety invariant, so it must be upheld any time a Pin<T> crosses an abstraction boundary (like being returned from your crate to the outside world, or being passed from your crate to a function you do not control).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants