-
Notifications
You must be signed in to change notification settings - Fork 0
AVec[T, A]
MaulingMonkey edited this page Feb 16, 2024
·
2 revisions
Given even the relatively simple:
type A = SomeNonZstAllocator;
struct S { pub a: AVec<u32, A>, pub b: AVec<u32, A> }
"Ideal" by-value borrowing is complicated:
struct Exclusive<'s> { pub a: &'s mut [u32], ... } // ❌ drops `Allocator` breaking ABI
struct Exclusive<'s> { pub a: &'s mut AVec<u32, A>, ... } // ❌ changes indirection, breaking ABI
struct Exclusive<'s> { pub a: Valrow<'s, AVec<u32, A>>, ... } // ❌ freezes `u32`s, preventing modification
struct Exclusive<'s> { pub a: ValrowMut<'s, AVec<u32, A>>, ... } // ❌ original value might UAF if vec resized
You more-or-less must have a custom partially-frozen type, which doesn't even deref into a shared-borrow:
type AVecValrowRef<'v, T, A> = valrow::Valrow<'a, AVec<T, A>>;
#[repr(transparent)] struct AVecValrowMut<'v, T, A>(ManuallyDrop<AVec<T, A>>, PhantomData<&'v mut AVec<T, A>>);
impl<'v, T, A> Deref for AVecValrowMut<'v, T, A> { fn deref (& self) -> & [T] { & self.0[..] } type Target = [T]; }
impl<'v, T, A> DerefMut for AVecValrowMut<'v, T, A> { fn deref_mut(&mut self) -> &mut [T] { &mut self.0[..] } }
impl<'v, T, A> From<AVecValrowMut<'v, T, A>> for AVecValrowRef<'v, T, A> { fn from(exc: ...) -> Self { unsafe { transmute(exc) } } }
And that still impacts downstream's codegen for S
:
struct Exclusive<'s> { pub a: AVecValrowMut<'s, u32, A>, ... }
struct Shared <'s> { pub a: AVecValrowRef<'s, u32, A>, ... }