Skip to content

Move "same size" requirement of transmute into a trait #1424

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

Open
gnzlbg opened this issue Dec 23, 2015 · 1 comment
Open

Move "same size" requirement of transmute into a trait #1424

gnzlbg opened this issue Dec 23, 2015 · 1 comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the RFC.

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Dec 23, 2015

Problem

Right now we cannot implement default trait methods that std::mem::transmute from Self into something else since the compiler doesn't know Selfs size, and thus std::mem::transmute's requirements cannot be verified:

trait Foo : Sized {  
    fn to_i32(self) -> i32 {
        unsafe {
            // lot's of types don't fulfill the requirements here: 
            std::mem::transmute::<Self, i32>(self)
        }
    }
}

impl Foo for u32 {}  // sad face :(

Possible solution

A cleaner way of enforcing std::mem::transmute requirements would be to enforce them with a trait:

unsafe trait Transmutable<U: Sized> : Sized {
    // warning magic inside!
}
unsafe impl Transmutable<U: Sized> for T { } // more magic

unsafe fn transmute<T: Transmutable<U>, U>(e: T) -> U

That is, instead of doing "compiler magic" at the fn transmute level, this magic could be lifted into a trait that constraints types on being Transmutable to each other.

That would allow the following code to type check:

// requires Self to be transmutable to i32:
trait Foo : Transmutable<i32> {  
    fn to_i32(self) -> i32 {
        unsafe {
            // the compilers knows that Self can be transmuted:
            std::mem::transmute::<Self, i32>(self)  // type-checks yay!
        }
    }
}

impl Foo for u32 {}

// impl Foo for u64 {}  // error: u64 is not `Transmutable<i32>`, yay!

Interaction with future language features

With type-level integers we will definitely want something analogous to a HasSize<u32> trait, and we will want to be able to std::mem::transmute between types of the same size. The Transmutable trait will still be useful, and can be implemented on top of HasSize if std::mem::size_of becomes a const fn. That is, this interaction between Transmutable and type-level integers can be solved in a backwards compatible way.

Bikeshedding

Instead of Transmutable the trait could also be called SameSize since that is exactly the constraint it imposes.

Implementability

No idea, haven't tried.

@nrc nrc added the T-libs-api Relevant to the library API team, which will review and decide on the RFC. label Aug 19, 2016
@burdges
Copy link

burdges commented Oct 12, 2016

I'd think #1144 should solve this for transmutes to/from fixed length array types, especially byte arrays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

3 participants