Skip to content

Commit 60fe3fe

Browse files
committed
Port Rust enum abomonation to NonNull-based interface
1 parent c0120ce commit 60fe3fe

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

src/lib.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,12 +337,17 @@ impl<T: Abomonation> Abomonation for Option<T> {
337337
}
338338
Ok(())
339339
}
340+
340341
#[inline(always)] unsafe fn exhume<'a>(self_: NonNull<Self>, mut bytes: &'a mut[u8]) -> Option<&'a mut [u8]> {
341-
if let &mut Some(ref mut inner) = self {
342-
let tmp = bytes; bytes = inner.exhume(tmp)?;
342+
// FIXME: This (briefly) constructs a "ref mut" to invalid data, which is UB.
343+
// I'm not sure if this can be fully resolved without relying on enum implementation details.
344+
if let Some(ref mut inner) = *self_.as_ptr() {
345+
let inner_ptr : NonNull<T> = From::from(inner);
346+
bytes = T::exhume(inner_ptr, bytes)?;
343347
}
344348
Some(bytes)
345349
}
350+
346351
#[inline] fn extent(&self) -> usize {
347352
self.as_ref().map(|inner| inner.extent()).unwrap_or(0)
348353
}
@@ -356,12 +361,22 @@ impl<T: Abomonation, E: Abomonation> Abomonation for Result<T, E> {
356361
};
357362
Ok(())
358363
}
364+
359365
#[inline(always)] unsafe fn exhume<'a>(self_: NonNull<Self>, bytes: &'a mut[u8]) -> Option<&'a mut [u8]> {
360-
match self {
361-
&mut Ok(ref mut inner) => inner.exhume(bytes),
362-
&mut Err(ref mut inner) => inner.exhume(bytes),
366+
// FIXME: This (briefly) constructs a "ref mut" to invalid data, which is UB.
367+
// I'm not sure if this can be fully resolved without relying on enum implementation details.
368+
match *self_.as_ptr() {
369+
Ok(ref mut inner) => {
370+
let inner_ptr : NonNull<T> = From::from(inner);
371+
T::exhume(inner_ptr, bytes)
372+
}
373+
Err(ref mut inner) => {
374+
let inner_ptr : NonNull<E> = From::from(inner);
375+
E::exhume(inner_ptr, bytes)
376+
}
363377
}
364378
}
379+
365380
#[inline] fn extent(&self) -> usize {
366381
match self {
367382
&Ok(ref inner) => inner.extent(),

0 commit comments

Comments
 (0)