Skip to content

[Question] Can we guarantee that the memory representation of a newtype will be equal to the representation of the type it wraps? #32146

Closed
@mitchmindtree

Description

@mitchmindtree

To clarify, given struct Foo<T>(T);, can we make the guarantee that Foo<T> will have the same memory representation as T?

I ask this as I have run into a couple of occasions where I would like to std::mem::transmute a slice of Foo<T> to a slice of T in some hot code.

I performed some tests and std::mem::size_of seems to consistently show Foo<T> to have the same size as T. The code below passes (playpen link).

struct Foo<T>(T);

fn assert_eq_size<T>() {
    assert_eq!(std::mem::size_of::<T>(), std::mem::size_of::<Foo<T>>());
    assert_eq!(std::mem::size_of::<&T>(), std::mem::size_of::<&Foo<T>>());
    assert_eq!(std::mem::size_of::<&[T]>(), std::mem::size_of::<&[Foo<T>]>());
}

#[allow(dead_code)]
fn main() {
    assert_eq_size::<i8>();
    assert_eq_size::<i16>();
    assert_eq_size::<i32>();
    assert_eq_size::<i64>();
    assert_eq_size::<u8>();
    assert_eq_size::<u16>();
    assert_eq_size::<u32>();
    assert_eq_size::<u64>();
    assert_eq_size::<f32>();
    assert_eq_size::<f64>();
    assert_eq_size::<isize>();
    assert_eq_size::<usize>();
    assert_eq_size::<bool>();
    struct Bar { a: i32, b: f64 }
    assert_eq_size::<Bar>();
    enum Baz { A(i32), B(usize), C(f64), D(u8) }
    assert_eq_size::<Baz>();
    trait Qux {}
    assert_eq_size::<&Qux>();
}

This leaves me wondering, what else might stand in the way? Is the use of std::mem::transmute I suggest above a bad idea? If so, why? Any input appreciated!

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: A feature request, i.e: not implemented / a PR.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions