Skip to content

Commit db5ec29

Browse files
committed
[WIP] Use ReadOnly in is_bit_valid
gherrit-pr-id: G7691845b6b02e9f3d9578435d732bacfa6ca674f
1 parent 45ff87c commit db5ec29

14 files changed

Lines changed: 491 additions & 270 deletions

File tree

src/impls.rs

Lines changed: 110 additions & 88 deletions
Large diffs are not rendered by default.

src/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,8 @@ const _: () = unsafe {
11031103
pub const STRUCT_VARIANT_ID: i128 = -1;
11041104
#[doc(hidden)]
11051105
pub const UNION_VARIANT_ID: i128 = -2;
1106+
#[doc(hidden)]
1107+
pub const REPR_C_UNION_VARIANT_ID: i128 = -3;
11061108

11071109
/// Projects a given field from `Self`.
11081110
///
@@ -1566,7 +1568,7 @@ pub unsafe trait TryFromBytes {
15661568
/// [`UnsafeCell`]: core::cell::UnsafeCell
15671569
/// [`Shared`]: invariant::Shared
15681570
#[doc(hidden)]
1569-
fn is_bit_valid<A: invariant::Reference>(candidate: Maybe<'_, Self, A>) -> bool;
1571+
fn is_bit_valid(candidate: Maybe<'_, Self>) -> bool;
15701572

15711573
/// Attempts to interpret the given `source` as a `&Self`.
15721574
///
@@ -2974,7 +2976,7 @@ unsafe fn try_read_from<S, T: TryFromBytes>(
29742976
// via `c_ptr` so long as it is live, so we don't need to worry about the
29752977
// fact that `c_ptr` may have more restricted validity than `candidate`.
29762978
let c_ptr = unsafe { c_ptr.assume_validity::<invariant::Initialized>() };
2977-
let c_ptr = c_ptr.transmute();
2979+
let mut c_ptr = c_ptr.cast::<_, crate::pointer::cast::CastSized, _>();
29782980

29792981
// Since we don't have `T: KnownLayout`, we hack around that by using
29802982
// `Wrapping<T>`, which implements `KnownLayout` even if `T` doesn't.
@@ -2987,7 +2989,7 @@ unsafe fn try_read_from<S, T: TryFromBytes>(
29872989
// `try_into_valid` (and thus `is_bit_valid`) with a shared pointer when
29882990
// `Self: !Immutable`. Since `Self: Immutable`, this panic condition will
29892991
// not happen.
2990-
if !Wrapping::<T>::is_bit_valid(c_ptr.forget_aligned()) {
2992+
if !Wrapping::<T>::is_bit_valid(c_ptr.reborrow_shared().forget_aligned()) {
29912993
return Err(ValidityError::new(source).into());
29922994
}
29932995

src/macros.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -895,10 +895,8 @@ macro_rules! cryptocorrosion_derive_traits {
895895
$($field_ty: $crate::FromBytes,)*
896896
)?
897897
{
898-
fn is_bit_valid<A>(_c: $crate::Maybe<'_, Self, A>) -> bool
899-
where
900-
A: $crate::pointer::invariant::Reference
901-
{
898+
#[inline]
899+
fn is_bit_valid(_c: $crate::Maybe<'_, Self>) -> bool {
902900
// SAFETY: This macro only accepts `#[repr(C)]` and
903901
// `#[repr(transparent)]` structs, and this `impl` block
904902
// requires all field types to be `FromBytes`. Thus, all
@@ -1038,10 +1036,8 @@ macro_rules! cryptocorrosion_derive_traits {
10381036
$field_ty: $crate::FromBytes,
10391037
)*
10401038
{
1041-
fn is_bit_valid<A>(_c: $crate::Maybe<'_, Self, A>) -> bool
1042-
where
1043-
A: $crate::pointer::invariant::Reference
1044-
{
1039+
#[inline]
1040+
fn is_bit_valid(_c: $crate::Maybe<'_, Self>) -> bool {
10451041
// SAFETY: This macro only accepts `#[repr(C)]` unions, and this
10461042
// `impl` block requires all field types to be `FromBytes`.
10471043
// Thus, all initialized byte sequences constitutes valid

src/pointer/mod.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ pub use {
2222
ptr::Ptr,
2323
};
2424

25+
use crate::wrappers::ReadOnly;
26+
2527
/// A shorthand for a maybe-valid, maybe-aligned reference. Used as the argument
2628
/// to [`TryFromBytes::is_bit_valid`].
2729
///
2830
/// [`TryFromBytes::is_bit_valid`]: crate::TryFromBytes::is_bit_valid
2931
pub type Maybe<'a, T, Aliasing = invariant::Shared, Alignment = invariant::Unaligned> =
30-
Ptr<'a, T, (Aliasing, Alignment, invariant::Initialized)>;
32+
Ptr<'a, ReadOnly<T>, (Aliasing, Alignment, invariant::Initialized)>;
3133

3234
/// Checks if the referent is zeroed.
3335
pub(crate) fn is_zeroed<T, I>(ptr: Ptr<'_, T, I>) -> bool
@@ -49,7 +51,7 @@ pub mod cast {
4951

5052
use crate::{
5153
layout::{SizeInfo, TrailingSliceLayout},
52-
HasField, KnownLayout, PtrInner,
54+
HasField, KnownLayout, PtrInner, REPR_C_UNION_VARIANT_ID,
5355
};
5456

5557
/// A pointer cast or projection.
@@ -361,6 +363,15 @@ pub mod cast {
361363
}
362364
}
363365

366+
// SAFETY: TODO
367+
unsafe impl<W: ?Sized, F, const FIELD_ID: i128>
368+
Cast<W, W::WrappedField> for WrappedProjection<W, F, { REPR_C_UNION_VARIANT_ID }, FIELD_ID>
369+
where
370+
W: Wrapped
371+
+ HasWrappedField<<<W as Wrapped>::Unwrapped as HasField<F, { REPR_C_UNION_VARIANT_ID }, FIELD_ID>>::Type>,
372+
W::Unwrapped: HasField<F, { REPR_C_UNION_VARIANT_ID }, FIELD_ID>,
373+
{}
374+
364375
/// A transitive sequence of projections.
365376
///
366377
/// Given `TU: Project` and `UV: Project`, `TransitiveProject<_, TU, UV>` is

0 commit comments

Comments
 (0)