Working with pinned slices / are there any structurally pinning Vec-like collection types?

As far as I’m understanding the requirement for structural pinning, slices in Rust do meet all the requirements for pinning to be structural over their elements.

  • The Unpin impl seems fitting
  • Drop is not explicitly implemented (so it can’t do evil) and panics from dropping the elements results in no destructor calls of succeeding elements being skipped (except for when the program aborts).
  • There are no operations leading to data being moved out of the slice when pinned (in fact, there are no operations at all handling pinned slices).

Yet I’m sorely missing functions in the standard library (or any crate I could find, for that matter—please point out any if they exist) with these signatures (with the obvious functionality)

(slice: Pin<&mut [T]>, index: usize) -> Pin<&mut T>
(self: Pin<&mut [T]>) -> impl Iterator<Item = Pin<&mut T>>

Am I missing something that makes these unsound? Are there any previous discussions on adding something to the standard library for this?


My actual goal here is just to have an owned collection of T: !Unpin values that allows me to obtain Pin<&mut T> references to its elements through indexing. If the operations described above were possible, I could use Pin<Box<[T]>> for this purpose. But perhaps (especially in case I’m missing some fundamental reasons against doing this with the actual slice type) there are alternative structually-pinned-collection-types out there; in which case, please point me to a crate.

4 Likes

Often when using Pin, you are forced to drop down to unsafe code, and I this appears to be a case where that is required.

As far as I know, both are sound if implemented correctly.

For the former, I opened a PR on rust repo: https://github.com/rust-lang/rust/pull/78370
For the latter, there is an internal utility that does this in the futures-util crate: https://github.com/rust-lang/futures-rs/blob/c4f734926f40d8c3e4bc50ad81483dc705a3c31c/futures-util/src/future/join_all.rs#L15

2 Likes