Why do we need Assume?

The ability to omit particular static checks makes BikeshedIntrinsicFrom useful in scenarios where aspects of well-definedness and safety are ensured through other means.

Example: Assuming Alignment

For the instantiation of a &'dst Dst from any &'src Src to be safe, the minimum required alignment of all Src must be stricter than the minimum required alignment of Dst, among other factors (e.g., 'src must outlive 'dst). By default, BikeshedIntrinsicFrom will enforce these requirements statically.

However, for the instantiation of a &'dst Dst from a particular &'src Src to be safe, we can just check that the alignment of that particular &'src Src is sufficient using mem::align_of (e.g., see bytemuck's try_cast_ref method).

Using a ASSUME parameter of Assume::ALIGNMENT makes BikeshedIntrinsicFrom useful in this scenario. With that ASSUME parameter, BikeshedIntrinsicFrom omits only its static alignment check, which we then assume responsibility to enforce ourselves; e.g.:

/// Try to convert a `&'src Src` into `&'dst Dst`.
///
/// This produces `None` if the referent isn't appropriately
/// aligned, as required by the destination type.
fn try_cast_ref<'src, 'dst, Src, Dst, Context>(src: &'src Src) -> Option<&'dst Dst>
where
    &'t T: BikeshedIntrinsicFrom<&'dst Dst, Context, Assume::ALIGNMENT>,
{
    // check alignment dynamically
    if (src as *const Src as usize) % align_of::<Dst>() != 0 {
        None
    } else {
        // SAFETY: we've dynamically enforced the alignment requirement.
        // `BikeshedIntrinsicFrom` statically enforces all other safety reqs.
        unsafe { &*(src as *const Src as *const Dst) }
    }
}