Soundness of DST with a size not multiple of aligment

⚓ Rust    📅 2025-07-02    👤 surdeus    👁️ 4      

surdeus

Warning

This post was published 35 days ago. The information described in this article may have changed.

I have code like this:

use core::ptr::NonNull;

#[repr(C, align(8))]
pub struct AlignedBytes(pub [u8]);

impl AlignedBytes {
    /// # Safety
    /// Same as [`slice::from_raw_parts`], but additionally
    /// the pointer MUST have alignment equal to 8.
    pub unsafe fn from_raw_parts<'a>(p: *const u8, len: usize) -> &'a Self {
        // note that casts between unsized pointers are allowed:
        // https://doc.rust-lang.org/reference/expressions/operator-expr.html#pointer-to-pointer-cast
        unsafe {
            let p = NonNull::new_unchecked(p as *mut u8);
            let p = NonNull::slice_from_raw_parts(p, len);
            &*(p.as_ptr() as *const Self)
        }
    }

    pub fn as_slice(&self) -> &[u8] {
        &self.0
    }
}

Technically, this code allows creation of &AlignedBytes with a length not multiple of the type alignment and Miri even accepts such code (playground). But the reference states the following:

The size of a value is always a multiple of its alignment.

Does it mean that the code in the playground is technically unsound?

3 posts - 3 participants

Read full topic

🏷️ rust_feed