Pin> vs. Box>
⚓ Rust 📅 2025-11-14 👤 surdeus 👁️ 5I'm failing to confidently understand pinning. Why are pinned pointers expressed as e.g. Pin<Box<T>> or Pin<&mut T> instead of Box<Pin<T>> or &mut Pin<T>?
Intuitively, you'd think that the former pattern expresses an immovable pointer to movable data, and the latter pattern expresses a movable pointer to immovable data. AFAICT, that intuition is wrong (although it seems to confuse the LLMs as much as it confuses me). In fact, I believe the former pattern expresses a movable pointer to immovable data. So, how could I express an immovable pointer to movable data? Is this some weird syntax inconsistency where established "pointer types" get special treatment with regard to Pin<T>?
More context:
I need to implement a self-referential data structure. The structure looks vaguely like this:
struct SelfReferentialCollection {
all_objects: Vec<Object>,
root: *const Object,
}
struct Object {
references: Vec<*const Object>,
}
The idea is that all of the objects are contained within that all_objects vector, and they can point to one another as long as they're all in the same collection. Yes, I tried implementing this with vector indices instead of pointers first, but it makes my algorithms way more complicated, so trust me that I actually want a self-referential type.
I believe I can see all the footguns lurking here. I know that I need to pre-allocate all the space the vector could possibly need on initialization with Vec::with_capacity, then only use push_within_capacity; never push. My understanding is that, as long as I'm extra careful to follow those rules, I don't really need to involve the Pin marker at all. The contents of the vector will not move.
But the docs even have a specific example where they discuss pinning the contents of a Vec, so I'm wondering if I should use something like Pin<Vec<Object>> or Vec<Pin<Object>> to express to readers "the contents of this vector should never move".
5 posts - 4 participants
🏷️ Rust_feed