summaryrefslogtreecommitdiff
path: root/rust/zerocopy/src/pointer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/zerocopy/src/pointer/mod.rs')
-rw-r--r--rust/zerocopy/src/pointer/mod.rs50
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>,
{
}