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
.
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)
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
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)