-
Notifications
You must be signed in to change notification settings - Fork 475
Description
It's currently impossible to have a pinned struct within the Lock<T> type. This is problematic, because drivers might want to do this for various reasons, specially as they grow in complexity.
A trivial example is:
#[pin_data]
struct Foo {
#[pin]
bar: Mutex<Bar>,
#[pin]
p: PhantomPinned,
}
#[pin_data]
struct Bar {
#[pin]
baz: Mutex<Baz>,
#[pin]
p: PhantomPinned,
}Note that Bar is pinned, so having it in a Mutex makes it impossible to instantiate a Foo that pins the Bar in bar. This is specially undesirable, since Foo is already pinned, and thus, it could trivially enforce that its bar field is pinned as well.
This can be trivially solved by using Pin<KBox<Bar>> instead of structurally pinning, at the cost of an extra (completely unneeded) allocation and ugly syntax. Furthermore, there is no support for pinned projections, so the following won't work:
let mut data: MutexGuard<'_, Data> = mutex.lock();
let mut data: Pin<&mut Data> = data.as_mut();
let a = &mut data.a; // <- won't compileThis task covers the work to make it possible to instantiate a Foo that pins its bar field.
We will start with the following changes, initially:
Changes needed for pinning the T in Mutex<T>:
- in
fn new()useimpl PinInit<T>instead ofT - the guard needs to only implement
DerefMutifT: Unpin - the guard needs to have
fn as_mut(&mut self) -> Pin<&mut T>
Here is a link to the relevant discussion on Zulip is.