Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement try_transmute! #1013

Closed
jswrenn opened this issue Mar 4, 2024 · 0 comments · Fixed by #1018
Closed

Implement try_transmute! #1013

jswrenn opened this issue Mar 4, 2024 · 0 comments · Fixed by #1018

Comments

@jswrenn
Copy link
Collaborator

jswrenn commented Mar 4, 2024

We should implement try_transmute!, analogous to transmute!, that performs compile-time size and alignment checks, but also a run-time validity check.

Considerations

Due to the run-time validity check, this macro will not be usable in const contexts for the foreseeable future. (But we could perhaps work around this by also providing const fn is_bit_valid inherent methods in our derive; see #115.)

The implementation should avoid performing dynamic size or alignment checks.

Steps

Once #999 is merged, we can define a typed alternative to is_bit_valid on TryFromBytes:

#[doc(hidden)]
#[inline]
fn is_src_valid<Src>(src: &mut Src) -> bool
where
    Src: IntoBytes,
    Self: Sized,
{
    let c_ptr = crate::Ptr::from_mut(src);

    if mem::size_of::<Src>() > mem::size_of::<Self>() {
        return false;
    }

    // SAFETY:
    // - `size_of::<Src>()` <= `size_of::<Self>()`
    // - `c_ptr` is exclusively aliased, so we do not need to reason about
    //   `UnsafeCell`
    let c_ptr = unsafe { c_ptr.cast_unsized(|p| p as *mut Self) };

    // SAFETY: `c_ptr` is derived from `src` which is `IntoBytes`. By
    // invariant on `IntoByte`s, `c_ptr`'s referent consists entirely of
    // initialized bytes.
    let c_ptr = unsafe { c_ptr.assume_validity::<crate::invariant::Initialized>() };

    Self::is_bit_valid(c_ptr)
}

The dynamic components of try_transmute! can then be factored into a helper function:

/// A helper for `try_transmute!`.
#[inline(always)]
pub fn try_transmute<Src, Dst>(mut src: Src) -> Option<Dst>
where
    Src: IntoBytes,
    Dst: TryFromBytes,
{
    if !Dst::is_src_valid(&mut src) {
        return None;
    }

    let src = ManuallyDrop::new(src);

    // SAFETY:
    // - `src` is a bit-valid instance of `Dst`
    // - `src` is `ManuallyDrop`
    Some(unsafe { core::mem::transmute_copy(&*src) })
}
jswrenn added a commit that referenced this issue Mar 4, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue Mar 4, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue Mar 4, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue Mar 5, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue Mar 5, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue Mar 5, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue Mar 5, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue Mar 13, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 13, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 13, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 13, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 13, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 14, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 14, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 14, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 14, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 14, 2024
Closes #1013.

Makes progress towards #5.
jswrenn added a commit that referenced this issue May 14, 2024
Closes #1013.

Makes progress towards #5.
github-merge-queue bot pushed a commit that referenced this issue May 14, 2024
Closes #1013.

Makes progress towards #5.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant