# Why is there no PinRc, PinArc, etc?

**URL:** <https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274>\
**Category:** libs\
**Created:** [August 23, 2018, 6:42am UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274 "2018-08-23T06:42:48Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tmccombs](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tmccombs/32/1845_2.png) [@tmccombs](https://internals.rust-lang.org/u/tmccombs)\
**Post date:** [August 23, 2018, 6:42am UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274/1 "2018-08-23T06:42:48Z")

</div>

Why is ther PinBox but not equivalents for Rc and Arc, or for that matter Vec?

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [August 23, 2018, 6:49am UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274/2 "2018-08-23T06:49:22Z")

</div>

You’re very lucky, @withoutboats posted a sort of reply for this just a few hours ago:

> **[Another look at the pinning API](https://boats.gitlab.io/blog/post/rethinking-pin/)**
>
> 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...

(EDIT: Although it doesn’t cover `Vec`, I don’t think it’s possible to have a collection of pinned objects similar to `Vec`, you could probably have some form of bucket allocated linked list as an alternative though).

---

<div class="post-metadata">

**Author:** ![tmccombs](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tmccombs/32/1845_2.png) [@tmccombs](https://internals.rust-lang.org/u/tmccombs)\
**Post date:** [August 24, 2018, 4:39am UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274/3 "2018-08-24T04:39:18Z")

</div>

Nice! I like it.

That actually could potentially add some support for `Vec` as well, with something like:

```rust
impl<T> From<Vec<T>> for Pin<Vec<T>> {
    fn from(pointer: Vec<T>) -> Pin<Vec<T>> {
        unsafe { Pin::new_unchecked(pointer) }
    }
}

impl<P, T> Pin<P>
where
    P: DerefMut<Target = [T]>,
{
    pub fn index_pin<'a, I>(&'a mut self, idx: I) -> Pin<&'a mut I::Output> 
    where 
        I: SliceIndex<[T]>,
        T: 'a
    {
        unsafe {Pin::new_unchecked(&mut self.pointer[idx]) }
    }
}

```

> <https://gist.github.com/tmccombs/7ea71f48a935f258837f038621f07b83>

Of course once you’ve moved the Vec into a Pin, you can’t add or remove elements, since that would move the contents. (So maybe it should be `impl<T> From<Vec<T>> for Pin<Box<[T]>>` instead?)

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [August 24, 2018, 5:21am UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274/4 "2018-08-24T05:21:06Z")

</div>

I think this would be written

```rust
let vec: Vec<_>;
vec.into_boxed_slice()
   .pin()

```

There’s no reason to support a pin over `Vec` specifically since `Vec` can’t be used to pin its contents. (As pushing would move its contents.)

---

<div class="post-metadata">

**Author:** ![gereeter](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gereeter/32/3175_2.png) [@gereeter](https://internals.rust-lang.org/u/gereeter)\
**Post date:** [August 24, 2018, 4:01pm UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274/5 "2018-08-24T16:01:37Z")

</div>

> [@CAD97](#):
>
> There’s no reason to support a pin over `Vec` specifically since `Vec` can’t be used to pin its contents. (As pushing would move its contents.)

Except that you can't call all the methods like `push` since you don't have a `&mut Vec`. I'm pretty sure that @tmccombs is right:

```rust
impl<T> From<Vec<T>> for Pin<Vec<T>> { /* ... */ }

```

is valid (using @withoutboats's new API). I don't think this should be restricted to `Box<[T]>`, since `Vec` can provide a lot more, in addition to not requiring a reallocation on creation. Going through the list of methods (just those on `Vec`, not those on `[]`), it seems to me that `clear`, `truncate`, and `set_len` should work without modification on `Pin<Vec>` and `push`, `append`, `resize`, `resize_with`, `resize_default`, and `extend_from_slice` can work if they are modified to return errors instead of reallocating when the `Vec` is at capacity.

It definitely is a more niche use case, and I don't think it would ever be possible to justify a standalone `PinVec` type in the standard library, but this is one of my favorite aspects of @withoutboats's new API: it allows for these more obscure cases without extra work.

---

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [August 24, 2018, 5:35pm UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274/6 "2018-08-24T17:35:57Z")

</div>

So in effect `Pin<Vec<_>>` would be a `Vec<_>` that never reallocated (grows bigger)? That actually seems useful separate from the pinning of its contents, though maybe not as useful as a stack vector.

You could implement an interpreter using a `Pin<Vec<Byte>>` as the stack, and an attempt to reallocate would be a stack overflow, and since the contents are pinned, references are sound. This sounds simultaneously silly, pointless, and fun.

---

<div class="post-metadata">

**Author:** ![gereeter](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gereeter/32/3175_2.png) [@gereeter](https://internals.rust-lang.org/u/gereeter)\
**Post date:** [August 24, 2018, 5:48pm UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274/7 "2018-08-24T17:48:10Z")

</div>

> [@CAD97](#):
>
> So in effect `Pin<Vec<_>>` would be a `Vec<_>` that never reallocated (grows bigger)?

Yes, though it occurs to me that it would actually be valid (if useless? you could just get a new `Vec`) to reallocate the `Vec` when it is empty.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:30am UTC](https://internals.rust-lang.org/t/why-is-there-no-pinrc-pinarc-etc/8274/8 "2019-03-25T08:30:46Z")

</div>

Closed on March 25, 2019, 8:30am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
