diff options
Diffstat (limited to 'rust/zerocopy/src/pointer/mod.rs')
| -rw-r--r-- | rust/zerocopy/src/pointer/mod.rs | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/rust/zerocopy/src/pointer/mod.rs b/rust/zerocopy/src/pointer/mod.rs index d6eacc52febe..0ce543391530 100644 --- a/rust/zerocopy/src/pointer/mod.rs +++ b/rust/zerocopy/src/pointer/mod.rs @@ -25,9 +25,9 @@ pub use transmute::*; use crate::wrappers::ReadOnly; /// A shorthand for a maybe-valid, maybe-aligned reference. Used as the argument -/// to [`TryFromBytes::is_bit_valid`]. +/// to [`TryFromBytes::is_safe`]. /// -/// [`TryFromBytes::is_bit_valid`]: crate::TryFromBytes::is_bit_valid +/// [`TryFromBytes::is_safe`]: crate::TryFromBytes::is_safe pub type Maybe<'a, T, Alignment = invariant::Unaligned> = Ptr<'a, ReadOnly<T>, (invariant::Shared, Alignment, invariant::Initialized)>; @@ -47,10 +47,7 @@ where pub mod cast { use core::{marker::PhantomData, mem}; - use crate::{ - layout::{SizeInfo, TrailingSliceLayout}, - HasField, KnownLayout, PtrInner, - }; + use crate::{layout::SizeInfo, HasField, KnownLayout, PtrInner}; /// A pointer cast or projection. /// @@ -182,11 +179,9 @@ pub mod cast { // SAFETY: By the `static_assert!`, `Src` and `Dst` are either: // - Both sized and equal in size - // - Both slice DSTs with the same trailing slice offset and element size - // and with align_of::<Src>() == align_of::<Dst>(). These ensure that any - // given pointer metadata encodes the same size for both `Src` and `Dst` - // (note that the alignment is required as it affects the amount of - // trailing padding). Thus, `project` preserves the set of referent bytes. + // - Both slice DSTs with the same trailing-slice offset, the same object + // size for every metadata value, and with align_of::<Src>() == + // align_of::<Dst>(). Thus, `project` preserves the set of referent bytes. unsafe impl<Src, Dst> Project<Src, Dst> for CastUnsized where Src: ?Sized + KnownLayout, @@ -201,10 +196,11 @@ pub mod cast { let dst = <Dst as KnownLayout>::LAYOUT; match (src.size_info, dst.size_info) { (SizeInfo::Sized { size: src_size }, SizeInfo::Sized { size: dst_size }) => src_size == dst_size, - ( - SizeInfo::SliceDst(TrailingSliceLayout { offset: src_offset, elem_size: src_elem_size }), - SizeInfo::SliceDst(TrailingSliceLayout { offset: dst_offset, elem_size: dst_elem_size }) - ) => src.align.get() == dst.align.get() && src_offset == dst_offset && src_elem_size == dst_elem_size, + (SizeInfo::SliceDst(src_trailing), SizeInfo::SliceDst(dst_trailing)) => { + src.align.get() == dst.align.get() + && src_trailing.offset == dst_trailing.offset + && src_trailing.has_same_size_sequence(dst_trailing) + }, _ => false, } }); @@ -225,10 +221,8 @@ pub mod cast { // SAFETY: By the `static_assert!` in `Project::project`, `Src` and `Dst` // are either: // - Both sized and equal in size - // - Both slice DSTs with the same alignment, trailing slice offset, and - // element size. These ensure that any given pointer metadata encodes the - // same size for both `Src` and `Dst` (note that the alignment is required - // as it affects the amount of trailing padding). + // - Both slice DSTs with the same alignment and trailing-slice offset, and + // with equal sizes for every metadata value. unsafe impl<Src, Dst> CastExact<Src, Dst> for CastUnsized where Src: ?Sized + KnownLayout, @@ -240,18 +234,22 @@ pub mod cast { /// /// A `Projection` is a [`Project`] which implements projection by /// delegating to an implementation of [`HasField::project`]. + /// + /// The `Client` parameter exists to select between implementations of + /// [`HasField`] that would otherwise conflict. #[allow(missing_debug_implementations, missing_copy_implementations)] - pub struct Projection<F: ?Sized, const VARIANT_ID: i128, const FIELD_ID: i128> { + pub struct Projection<Client, F: ?Sized, const VARIANT_ID: i128, const FIELD_ID: i128> { _never: core::convert::Infallible, + _client: PhantomData<Client>, _phantom: PhantomData<F>, } // SAFETY: `HasField::project` has the same safety post-conditions as // `Project::project`. - unsafe impl<T: ?Sized, F, const VARIANT_ID: i128, const FIELD_ID: i128> Project<T, T::Type> - for Projection<F, VARIANT_ID, FIELD_ID> + unsafe impl<T: ?Sized, Client, F, const VARIANT_ID: i128, const FIELD_ID: i128> + Project<T, T::Type> for Projection<Client, F, VARIANT_ID, FIELD_ID> where - T: HasField<F, VARIANT_ID, FIELD_ID>, + T: HasField<Client, F, VARIANT_ID, FIELD_ID>, { #[inline(always)] fn project(src: PtrInner<'_, T>) -> *mut T::Type { @@ -292,10 +290,10 @@ pub mod cast { // // FIXME(https://github.com/rust-lang/unsafe-code-guidelines/issues/595): // Cite the documentation once it's updated. - unsafe impl<T: ?Sized, F, const FIELD_ID: i128> Cast<T, T::Type> - for Projection<F, { crate::REPR_C_UNION_VARIANT_ID }, FIELD_ID> + unsafe impl<T: ?Sized, Client, F, const FIELD_ID: i128> Cast<T, T::Type> + for Projection<Client, F, { crate::REPR_C_UNION_VARIANT_ID }, FIELD_ID> where - T: HasField<F, { crate::REPR_C_UNION_VARIANT_ID }, FIELD_ID>, + T: HasField<Client, F, { crate::REPR_C_UNION_VARIANT_ID }, FIELD_ID>, { } |
