Skip to content

Unexpected alignment of repr(packed) struct containing a DST #2632

@nicholasbishop

Description

@nicholasbishop

Example code (playground link)

#![feature(layout_for_ptr, ptr_metadata)]
use std::{mem, ptr};

#[repr(C, packed)]
struct A {
    f: u32,
}

#[repr(C, packed)]
struct B {
    f: [u32],
}

fn main() {
    let a = A { f: 0 };
    dbg!(mem::align_of_val(&a));

    let storage = [0u8; 4];
    let b: *const B = ptr::from_raw_parts(storage.as_ptr().cast(), 1);

    dbg!(unsafe { mem::align_of_val_raw(b) });
}

Running this outside of Miri gives the output I would expect; values of A and B both have an alignment of 1:

[src/main.rs:16] mem::align_of_val(&a) = 1
[src/main.rs:21] unsafe { mem::align_of_val_raw(b) } = 1

But when running under Miri, I get this instead:

[src/main.rs:16] mem::align_of_val(&a) = 1
[src/main.rs:21] unsafe { mem::align_of_val_raw(b) } = 4

I would have expected the alignment of B to be 1 since it is repr(packed). https://doc.rust-lang.org/nomicon/other-reprs.html#reprpacked says "repr(packed) forces Rust to strip any padding, and only align the type to a byte", and doesn't mention an exception for DSTs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions