Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion src/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ where

#[doc(hidden)]
pub mod cast {
use core::{marker::PhantomData, mem};
use core::{
marker::PhantomData,
mem::{self, MaybeUninit},
num::Wrapping,
};

use crate::{
layout::{SizeInfo, TrailingSliceLayout},
Expand Down Expand Up @@ -255,6 +259,67 @@ pub mod cast {
}
}

// TODO: Do these need to be unsafe? The casts they carry have their own
// safety invariants by trait bound. Perhaps we need them to also carry
// *validity* implications when we use them later for projection on `Ptr`s?
Comment thread
joshlf marked this conversation as resolved.

/// TODO
///
/// # Safety
///
/// TODO
Comment thread
joshlf marked this conversation as resolved.
pub unsafe trait Wrapped {
type Unwrapped: ?Sized;
type CastToUnwrapped: CastExact<Self, Self::Unwrapped>;
type CastFromUnwrapped: CastExact<Self::Unwrapped, Self>;
}

/// TODO
///
/// # Safety
///
/// TODO
Comment thread
joshlf marked this conversation as resolved.
pub unsafe trait HasWrappedField<F: ?Sized>: Wrapped {
type WrappedField: ?Sized + Wrapped<Unwrapped = F>;
}

// SAFETY: TODO
Comment thread
joshlf marked this conversation as resolved.
unsafe impl<T> Wrapped for MaybeUninit<T> {
type Unwrapped = T;
type CastToUnwrapped = CastSizedExact;
type CastFromUnwrapped = CastSizedExact;
}

// SAFETY: TODO
Comment thread
joshlf marked this conversation as resolved.
unsafe impl<T, F> HasWrappedField<F> for MaybeUninit<T> {
type WrappedField = MaybeUninit<F>;
}

// SAFETY: TODO
Comment thread
joshlf marked this conversation as resolved.
unsafe impl<T> Wrapped for Wrapping<T> {
type Unwrapped = T;
type CastToUnwrapped = CastSizedExact;
type CastFromUnwrapped = CastSizedExact;
}

// SAFETY: TODO
Comment thread
joshlf marked this conversation as resolved.
unsafe impl<T, F> HasWrappedField<F> for Wrapping<T> {
type WrappedField = Wrapping<F>;
}

pub type WrappedProjection<W, F, const VARIANT_ID: i128, const FIELD_ID: i128> =
TransitiveProject<
<<W as Wrapped>::Unwrapped as HasField<F, VARIANT_ID, FIELD_ID>>::Type,
TransitiveProject<
<W as Wrapped>::Unwrapped,
<W as Wrapped>::CastToUnwrapped,
Projection<F, VARIANT_ID, FIELD_ID>,
>,
<<W as HasWrappedField<
<<W as Wrapped>::Unwrapped as HasField<F, VARIANT_ID, FIELD_ID>>::Type,
>>::WrappedField as Wrapped>::CastFromUnwrapped,
>;
Comment thread
joshlf marked this conversation as resolved.

/// A transitive sequence of projections.
///
/// Given `TU: Project` and `UV: Project`, `TransitiveProject<_, TU, UV>` is
Expand Down
12 changes: 12 additions & 0 deletions src/wrappers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,18 @@ const _: () = {
impl<T: ?Sized> SizeEq<T> for ReadOnly<T> {
type CastFrom = CastToReadOnly;
}

// SAFETY: TODO
Comment thread
joshlf marked this conversation as resolved.
unsafe impl<T: ?Sized> crate::pointer::cast::Wrapped for ReadOnly<T> {
type Unwrapped = T;
type CastToUnwrapped = CastFromReadOnly;
type CastFromUnwrapped = CastToReadOnly;
}

// SAFETY: TODO
Comment thread
joshlf marked this conversation as resolved.
unsafe impl<T: ?Sized, F: ?Sized> crate::pointer::cast::HasWrappedField<F> for ReadOnly<T> {
type WrappedField = ReadOnly<F>;
}
};

// SAFETY: `ReadOnly<T>` is a `#[repr(transparent)]` wrapper around `T`, and so
Expand Down
Loading