Entries tagged - "pinning"

Three problems of pinning


When we developed the Pin API, our vision was that “ordinary users” - that is, users using the “high-level” registers of Rust, would never have to interact with it. We intended that only users implementing Futures by hand, in the “low-level” register, would have to deal with that additional complexity. And the benefit that would accrue to all users is that futures, being immovable while polling, could store self-references in their state.

Things haven’t gone perfectly according to plan. The benefits of Pin have certainly been accrued - everyone is writing self-referential async functions all the time, and low-level concurrency primitives in all the major runtimes take advantage of Pin to implement intrusive linked lists internally. But Pin still sometimes rears its ugly head into “high-level” code, and users are unsurprisingly frustrated and confused when that happens.

In my experience, there a three main ways that this happens. Two of them can be solved by better affordances for AsyncIterator (a part of why I have been pushing stabilizing this so hard!). The third is ultimately because of a mistake that we made when we designed Pin, and without a breaking change there’s nothing we could about it. They are:

  1. Selecting a Future in a loop.
  2. Calling Stream::next.
  3. Awaiting a Future behind a pointer (e.g. a boxed future).

New crate: pin-cell


Today I realized a new crate called pin-cell. This crate contains a type called PinCell, which is a kind of cell that is similar to RefCell, but only can allow pinned mutable references into its interior. Right now, the crate is nightly only and no-std compatible. How is the API of PinCell different from RefCell? When you call borrow_mut on a RefCell, you get a type back that implements DerefMut, allowing you to mutate the interior value.…

Another look at the pinning API


A few months ago we introduced the concept of “pinned” references - pointers which “pin” the data they refer to in a particular memory location, guaranteeing that it will never move again. These are an important building block for certain patterns that had previously been hard for Rust to handle, like self-referential structs and intrusive lists, and we’ve in the process of considering stabilizing the API. One thing has always nagged about the API we have right now though: the proliferation of different reference types that it implies.…