Rust: mem::transmute should be a `const fn`.

Created on 28 Mar 2018  路  8Comments  路  Source: rust-lang/rust

A common request in stdsimd is being able to initialize static variables with architecture-specific vector types.

There are many ways to hack this out, but AFAICt all of them basically reduce to using an union to implement a mem::transmute clone whose only different from mem::transmute is that it is a const fn.

Since this is already possible today, we should IMO just go ahead and make mem::transmute a const fn.

A-const-fn C-enhancement T-libs

Most helpful comment

This has now been implemented behind a feature gate: https://github.com/rust-lang/rust/pull/53535

The tracking issue is https://github.com/rust-lang/rust/issues/53605 . Please raise any objections to the stabilization there.

My personal stance is that if we do not stabilize it, but allow unions in const fn, then users will just write

union Transmute<T, U> {
    t: T,
    u: U,
}
pub const unsafe fn my_hacky_transmute<T, U>(t: T) -> U {
    Transmute { t }.u
}

and everything will be worse with that than with transmute being const fn and having a bunch of type checks (size checks and lints about statically known bad transmutes)

All 8 comments

The union-in-const transmute trick is actually already stable on nightly (without const fn, even), but only works on Copy types (which may work for SIMD, right?). Here's an example: https://play.rust-lang.org/?gist=c4c0b2c82ce182243d506b24af7d2e1c&version=nightly

@solson yes, that's what I meant with:

There are many ways to hack this out, but AFAICt all of them basically reduce to using an union to implement a mem::transmute clone whose only different from mem::transmute is that it is a const fn.

I'm ideologically opposed to the generality and special-ness of transmute anyway, so I'm not a big fan of extending it or making it more general in any way. For the SIMD use case specifically, I'd rather see safe reinterpreting methods/constructors, analogous to f32::{to,from}_bits.

For the SIMD use case specifically, I'd rather see safe reinterpreting methods/constructors, analogous to f32::{to,from}_bits.

These methods call transmute under the covers, and if transmute is not a const fn they basically have to re-implement their own transmute function that is.

Yes, and I am fine with that. It's an acceptable trade off for not presenting const fn transmute to users.

Yes, and I am fine with that. It's an acceptable trade off for not presenting const fn transmute to users.

The stdsimd crate currently offers FromBits/IntoBits traits that do what the f32/f64::from_bits functions do, but currently can't be const because trait methods can't be const (we could make these inherent methods by using from_{type}_bits or similar).

The current problem with this approach is that it requires O(N^2) implementations. A Compatible<T> approach like the one discussed here would be better, but it would still need const fn in trait methods.

But these are issues for any interface that is more specific than transmute, right? We'll definitely want such interfaces, so those problems needs solving in any case.

This has now been implemented behind a feature gate: https://github.com/rust-lang/rust/pull/53535

The tracking issue is https://github.com/rust-lang/rust/issues/53605 . Please raise any objections to the stabilization there.

My personal stance is that if we do not stabilize it, but allow unions in const fn, then users will just write

union Transmute<T, U> {
    t: T,
    u: U,
}
pub const unsafe fn my_hacky_transmute<T, U>(t: T) -> U {
    Transmute { t }.u
}

and everything will be worse with that than with transmute being const fn and having a bunch of type checks (size checks and lints about statically known bad transmutes)

Was this page helpful?
0 / 5 - 0 ratings