-
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 compile
This 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
DerefMut
ifT: 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.