Skip to content
Merged
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
4 changes: 2 additions & 2 deletions src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ const _: () = {
}

#[inline(always)]
fn project_raw(slf: PtrInner<'_, Self>) -> *mut T {
fn project(slf: PtrInner<'_, Self>) -> *mut T {
// SAFETY: `ManuallyDrop<T>` has the same layout and bit validity as
// `T` [1].
//
Expand Down Expand Up @@ -1084,7 +1084,7 @@ mod tuples {
type Type = $CurrT;

#[inline(always)]
fn project_raw(slf: crate::PtrInner<'_, Self>) -> *mut Self::Type {
fn project(slf: crate::PtrInner<'_, Self>) -> *mut Self::Type {
let slf = slf.as_non_null().as_ptr();
// SAFETY: `PtrInner` promises it references either a zero-sized
// byte range, or else will reference a byte range that is
Expand Down
37 changes: 3 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,46 +1140,15 @@ pub unsafe trait HasField<Field, const VARIANT_ID: i128, const FIELD_ID: i128> {

/// Projects from `slf` to the field.
///
/// # Safety
///
/// The returned pointer refers to a non-strict subset of the bytes of
/// `slf`'s referent, and has the same provenance as `slf`.
fn project_raw(slf: PtrInner<'_, Self>) -> *mut Self::Type;

/// Projects from `slf` to the field.
/// Users should generally not call `project` directly, and instead should
/// use high-level APIs like [`PtrInner::project`] or [`Ptr::project`].
///
/// # Safety
///
/// The returned pointer refers to a non-strict subset of the bytes of
/// `slf`'s referent, and has the same provenance as `slf`.
#[must_use]
#[inline(always)]
fn project_inner(slf: PtrInner<'_, Self>) -> PtrInner<'_, Self::Type> {
let projected_raw = Self::project_raw(slf);
// SAFETY: `slf`'s referent lives at a `NonNull` address, and is either
// zero-sized or lives in an allocation. In either case, it does not
// wrap around the address space [1], and so none of the addresses
// contained in it or one-past-the-end of it are null.
//
// By invariant on `project_raw`, `project_raw` is a
// provenance-preserving projection which preserves or shrinks the set
// of referent bytes, so `projected_raw` references a subset of `slf`'s
// referent, and so it cannot be null.
//
// [1] https://doc.rust-lang.org/1.92.0/std/ptr/index.html#allocation
let projected_non_null = unsafe { NonNull::new_unchecked(projected_raw) };
// SAFETY: As described in the preceding safety comment,
// `projected_raw`, and thus `projected_non_null`, addresses a subset of
// `slf`'s referent. Thus, `projected_non_null` either:
// - Addresses zero bytes or,
// - Addresses a subset of the referent of `slf`. In this case, `slf`
// has provenance for its referent, which lives in an allocation.
// Since `projected_non_null` was constructed using a sequence of
// provenance-preserving operations, it also has provenance for its
// referent and that referent lives in an allocation. By invariant on
// `slf`, that allocation lives for `'a`.
unsafe { PtrInner::new(projected_non_null) }
}
fn project(slf: PtrInner<'_, Self>) -> *mut Self::Type;
}

/// Analyzes whether a type is [`FromZeros`].
Expand Down
10 changes: 8 additions & 2 deletions src/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ pub mod cast {
pub unsafe trait Project<Src: ?Sized, Dst: ?Sized> {
/// Projects a pointer from `Src` to `Dst`.
///
/// Users should generally not call `project` directly, and instead
/// should use high-level APIs like [`PtrInner::project`] or
/// [`Ptr::project`].
///
/// [`Ptr::project`]: crate::pointer::Ptr::project
///
/// # Safety
///
/// The returned pointer refers to a non-strict subset of the bytes of
Expand Down Expand Up @@ -173,7 +179,7 @@ pub mod cast {
/// A field projection
///
/// A `Projection` is a [`Project`] which implements projection by
/// delegating to an implementation of [`HasField::project_raw`].
/// delegating to an implementation of [`HasField::project`].
#[allow(missing_debug_implementations, missing_copy_implementations)]
pub struct Projection<F: ?Sized, const VARIANT_ID: i128, const FIELD_ID: i128> {
_never: core::convert::Infallible,
Expand All @@ -189,7 +195,7 @@ pub mod cast {
{
#[inline(always)]
fn project(src: PtrInner<'_, T>) -> *mut T::Type {
T::project_raw(src)
T::project(src)
}
}

Expand Down
4 changes: 2 additions & 2 deletions zerocopy-derive/src/enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ pub(crate) fn derive_is_bit_valid(
type Type = #ty;

#[inline(always)]
fn project_raw(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut Self::Type {
fn project(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut Self::Type {
use #zerocopy_crate::pointer::cast::{CastSized, Projection};

slf.project::<___ZerocopyRawEnum #ty_generics, CastSized>()
Expand Down Expand Up @@ -410,7 +410,7 @@ pub(crate) fn derive_is_bit_valid(
type Type = ___ZerocopyTag;

#[inline(always)]
fn project_raw(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut Self::Type {
fn project(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut Self::Type {
slf.as_ptr().cast()
}
}
Expand Down
2 changes: 1 addition & 1 deletion zerocopy-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,7 @@ fn derive_has_field_struct_union(
type Type = #ty;

#[inline(always)]
fn project_raw(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut Self::Type {
fn project(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut Self::Type {
let slf = slf.as_ptr();
// SAFETY: By invariant on `PtrInner`, `slf` is a non-null
// pointer whose referent is zero-sized or lives in a valid
Expand Down
Loading
Loading