Skip to content

Commit 622633b

Browse files
committed
[WIP] ReadOnly + TryFromBytes::is_bit_valid
gherrit-pr-id: Gb15e30e716a041285c1bf7434ce3163f594526a7
1 parent ba1a532 commit 622633b

2 files changed

Lines changed: 90 additions & 1 deletion

File tree

src/pointer/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub use {
2727
///
2828
/// [`TryFromBytes::is_bit_valid`]: crate::TryFromBytes::is_bit_valid
2929
pub type Maybe<'a, T, Aliasing = invariant::Shared, Alignment = invariant::Unaligned> =
30-
Ptr<'a, T, (Aliasing, Alignment, invariant::Initialized)>;
30+
Ptr<'a, crate::wrappers::ReadOnly<T>, (Aliasing, Alignment, invariant::Initialized)>;
3131

3232
/// Checks if the referent is zeroed.
3333
pub(crate) fn is_zeroed<T, I>(ptr: Ptr<'_, T, I>) -> bool

src/wrappers.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use core::{fmt, hash::Hash};
1010

1111
use super::*;
12+
use crate::pointer::{invariant::Valid, SizeEq, TransmuteFrom};
1213

1314
/// A type with no alignment requirement.
1415
///
@@ -594,6 +595,94 @@ impl<T: ?Sized + KnownLayout> fmt::Debug for MaybeUninit<T> {
594595
}
595596
}
596597

598+
/// TODO
599+
#[cfg_attr(any(feature = "derive", test), derive(FromBytes, IntoBytes, Unaligned))]
600+
#[repr(transparent)]
601+
pub struct ReadOnly<T: ?Sized>(T);
602+
603+
const _: () = unsafe {
604+
unsafe_impl_known_layout!(T: ?Sized + KnownLayout => #[repr(T)] ReadOnly<T>);
605+
};
606+
607+
// SAFETY:
608+
// - `ReadOnly<T>` has the same alignment as `T`, and so it is `Unaligned`
609+
// exactly when `T` is as well.
610+
// - `ReadOnly<T>` has the same bit validity as `T`, and so it is `FromZeros`,
611+
// `FromBytes`, or `IntoBytes` exactly when `T` is as well.
612+
// - `TryFromBytes`: `ReadOnly<T>` has the same the same bit validity as `T`, so
613+
// `T::is_bit_valid` is a sound implementation of `is_bit_valid`.
614+
#[allow(unused_unsafe)] // Unused when `feature = "derive"`.
615+
const _: () = unsafe {
616+
impl_or_verify!(T: ?Sized + Unaligned => Unaligned for ReadOnly<T>);
617+
impl_or_verify!(
618+
T: ?Sized + TryFromBytes => TryFromBytes for ReadOnly<T>;
619+
|c| T::is_bit_valid(c.transmute::<_, _, BecauseImmutable>())
620+
);
621+
impl_or_verify!(T: ?Sized + FromZeros => FromZeros for ReadOnly<T>);
622+
impl_or_verify!(T: ?Sized + FromBytes => FromBytes for ReadOnly<T>);
623+
impl_or_verify!(T: ?Sized + IntoBytes => IntoBytes for ReadOnly<T>);
624+
};
625+
626+
const _: () = unsafe {
627+
unsafe_impl!(T: ?Sized => Immutable for ReadOnly<T>);
628+
};
629+
630+
const _: () = {
631+
// SAFETY: TODO
632+
define_cast!(unsafe { pub CastFromReadOnly<T: ?Sized> = ReadOnly<T> => T});
633+
// SAFETY: TODO
634+
define_cast!(unsafe { pub CastToReadOnly<T: ?Sized> = T => ReadOnly<T>});
635+
636+
unsafe impl<T: ?Sized> SizeEq<ReadOnly<T>> for T {
637+
type CastFrom = CastFromReadOnly;
638+
}
639+
640+
unsafe impl<T: ?Sized> SizeEq<T> for ReadOnly<T> {
641+
type CastFrom = CastToReadOnly;
642+
}
643+
};
644+
645+
unsafe impl<T: ?Sized> TransmuteFrom<T, Valid, Valid> for ReadOnly<T> {}
646+
unsafe impl<T: ?Sized> TransmuteFrom<ReadOnly<T>, Valid, Valid> for T {}
647+
648+
impl<T> ReadOnly<T> {
649+
/// TODO
650+
#[inline(always)]
651+
pub const fn new(t: T) -> ReadOnly<T> {
652+
ReadOnly(t)
653+
}
654+
}
655+
656+
impl<T: ?Sized + Immutable> Deref for ReadOnly<T> {
657+
type Target = T;
658+
659+
#[inline(always)]
660+
fn deref(&self) -> &Self::Target {
661+
&self.0
662+
}
663+
}
664+
665+
impl<T: ?Sized + Immutable> DerefMut for ReadOnly<T> {
666+
#[inline(always)]
667+
fn deref_mut(&mut self) -> &mut Self::Target {
668+
&mut self.0
669+
}
670+
}
671+
672+
impl<'a, T: ?Sized + Immutable> From<&'a T> for &'a ReadOnly<T> {
673+
#[inline(always)]
674+
fn from(t: &'a T) -> &'a ReadOnly<T> {
675+
todo!()
676+
}
677+
}
678+
679+
impl<T: ?Sized + Immutable + Debug> Debug for ReadOnly<T> {
680+
#[inline(always)]
681+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
682+
self.deref().fmt(f)
683+
}
684+
}
685+
597686
#[cfg(test)]
598687
mod tests {
599688
use core::panic::AssertUnwindSafe;

0 commit comments

Comments
 (0)