4 ms·
I'm not particularly familiar with Pinned but the documentation on std::pin suggests it prevents moving data, not copying data (and is primarily designed around
by eridius 8y ago
I'm not particularly familiar with Pinned but the documentation on std::pin suggests it prevents moving data, not copying data (and is primarily designed around enabling self-referential structs).
- legulere 8y agoMoves are exactly the problem, as the data is just copied, without drop running on the source, and they happen implicitly.
- eridius 8y agoRust isn't going to just silently move the pointed-to data in something like Box<[u8; 32]>. It looks like the point of Pinned is to protect against operations like swap() that would move the pointed-to data, but the point here is to maintain the data's invariants (e.g. a self-referential struct cannot be moved or its self-references would be invalid) rather than to protect against silent moves (a call to swap() is definitely not silent).
- masklinn 8y ago> Rust isn't going to just silently move the pointed-to data in something like Box<[u8; 32]>. Of course not, but for efficiency you might have an [u8;32][0] instead and that will get memcpy'd when it's moved around. [0] 32 bytes on the stack isn't much, a single Vec or String is 24
- eridius 8y agoA [u8;32] doesn't work with Pin. Pin only works when you wrap it around a pointer type. From the documentation on Unpin: > Since Rust itself has no notion of immovable types, and will consider moves to always be safe, this trait cannot prevent types from moving by itself. From the documentation on std::pin: > In order to prevent objects from moving, they must be pinned by wrapping a pointer to the data in the Pin type. A pointer wrapped in a Pin is otherwise equivalent to its normal version, e.g. Pin<Box<T>> and Box<T> work the same way except that the first is pinning the value of T in place. > First of all, these are pointer types because pinned data mustn't be passed around by value (that would change its location in memory). … Looking at Pin itself, it appears that it works by only implementing DerefMut if its target is Unpin, thus preventing you from mutating (and therefore swapping/replacing) the data unless the data supports Unpin. But beyond that, it also only implements Deref and DerefMut if its wrapped type itself implements Deref/DerefMut, which means using Pin around a non-pointer basically prevents you from accessing the wrapped data.
- deleted 8y ago[deleted]
- kibwen 8y agoAFAIK the purpose of pinning is to statically ensure that the pinned data remains at the current address in memory, for the purpose of handing out references to the data that remain valid even if the precise lifetime of those references isn't statically known (the soundness and safety of Rust's async story relies on this property holding, so the devs are incentivized to uphold it). I won't claim to be able prove that it's impossible for a too-smart compiler to still somehow manage to have pinned data lingering somewhere else in memory, but it should be a good start.