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

[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 opened this issue Mar 9, 2016 · 8 comments
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@mitchmindtree
Copy link
Contributor

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!

@eddyb
Copy link
Member

eddyb commented Mar 9, 2016

C ABIs don't guarantee this btw, aggregates are treated differently than the types they contain, in general, but it depends on the types (I believe a newtype of a pointer will work in all the ABIs we support?).

For more information, see all the cabi_* modules in trans and the equivalent code in clang.

@apasel422
Copy link
Contributor

CC #29702.

@bluss
Copy link
Member

bluss commented Mar 9, 2016

Just for completeness, a Drop impl on the Foo<T> will stand in the way, so it would need to be conditional on that (for now).

@bluss
Copy link
Member

bluss commented Mar 9, 2016

C has the guarantee that you can cast between a pointer-to-struct and a pointer to the type of the first field of the struct. That would be useful.

@steveklabnik
Copy link
Member

/cc @rust-lang/lang

@nrc
Copy link
Member

nrc commented Mar 14, 2016

This is part of the bigger question of what kind of ABI guarantees we are providing. We should probably consider that question as a whole rather than providing a bunch of smaller, ad hoc, and poorly documented guarantees.

@steveklabnik steveklabnik added T-lang Relevant to the language team, which will review and decide on the PR/issue. and removed A-lang labels Mar 24, 2017
@Mark-Simulacrum
Copy link
Member

See rust-lang/rfcs#1758 for an RFC proposing a repr for this, I believe.

@Mark-Simulacrum Mark-Simulacrum added the C-feature-request Category: A feature request, i.e: not implemented / a PR. label Jul 24, 2017
@Havvy
Copy link
Contributor

Havvy commented Jun 30, 2018

Triage: This can be closed, as it's answered with "use the transparent representation".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: A feature request, i.e: not implemented / a PR. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

9 participants