I'm going through the FrozenVec<T>
implementation in elsa
and I can't figure out how it's safe.
Internally a FrozenVec<T>
is just a Vec<T>
:
pub struct FrozenVec<T> {
vec: UnsafeCell<Vec<T>>,
}
The idea behind the crate is that you can push a T
with just a &FrozenVec<T>
, but you can't get a &mut T
back. This is the implementation:
pub fn push_get(&self, val: T) -> &T::Target {
unsafe {
let vec = self.vec.get();
(*vec).push(val);
&*(&**(*vec).get_unchecked((*vec).len() - 1) as *const T::Target)
}
}
However my understanding was that, whenever Vec<T>
's size reached 2n + 1
where n is a natural number, the Vec<T>
will have to reallocate and (potentially) move all of its items. This means that, if I push 16 items into a Vec<T>
and then push one more, a reference to any one of those 16 items should be invalidated. Am I missing something here?