Rust: Tracking Issue for using std::mem::transmute() in const fn (const_fn_transmute)

Created on 22 Aug 2018  路  12Comments  路  Source: rust-lang/rust

Using std::mem::transmute() in constant functions is behind the const_transmute/const_fn_transmute feature gate.
(In constants, it is stable.)

Blocked on https://github.com/rust-lang/const-eval/issues/14.

A-const-eval A-const-fn B-unstable C-tracking-issue Libs-Tracked T-lang T-libs requires-nightly

Most helpful comment

unsafe in const fn has been stabilized in 1.33. Is there anything else left preventing this from being stabilized as well?

EDIT: Ugh, in fact, there is. For example, usize -> function pointer throws

error[E0080]: it is undefined behavior to use this value
...
type validation failed: encountered 10220800, but expected a pointer
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior

... which makes const_transmute pretty much useless for me.

All 12 comments

I, for one, would love this, because I've had to use the union transmute hack more times than I feel comfortable. std::mem::transmute is still (super) unsafe, but at least it makes sure the types have the same size.

@mjbshaw It's already been merged :)

@TheDarkula I know. I'm just trying to show support for eventually stabilizing this feature (rather than being removed because people are opposed to it).

Even with the flag, is this possible? I am getting an error stating that the use of unsafe functions are not allowed in const fn:

pub const unsafe fn rx_buffer_init() -> [BufferDescriptor; BUFFER_CT] {
    transmute::<
        [u8; size_of::<BufferDescriptor>() * BUFFER_CT],
        [BufferDescriptor; BUFFER_CT]
    >([0u8; size_of::<BufferDescriptor>() * BUFFER_CT])
}

gives me

error: call to unsafe function is unsafe and unsafe operations are not allowed in const fn
  --> foo/src/test.rs:18:5
   |
18 | /     transmute::<
19 | |         [u8; size_of::<BufferDescriptor>() * BUFFER_CT],
20 | |         [BufferDescriptor; BUFFER_CT]
21 | |     >([0u8; size_of::<BufferDescriptor>() * BUFFER_CT])
   | |____________________________________________________________^ call to unsafe function
   |
   = note: consult the function's documentation for information on how to avoid undefined behavior

Is there some blocker on this or could this be starting to get stabilized? I'm mostly looking out for a way to define a function from a u8 array without any indirection but I have no idea whether this is supposed to be supported or not in the design of const fn.

unsafe in const fn has been stabilized in 1.33. Is there anything else left preventing this from being stabilized as well?

EDIT: Ugh, in fact, there is. For example, usize -> function pointer throws

error[E0080]: it is undefined behavior to use this value
...
type validation failed: encountered 10220800, but expected a pointer
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior

... which makes const_transmute pretty much useless for me.

Given that union field access is already possible inside const (but not inside const fn), it seems somewhat silly to block transmute. All that does is make code less readable by pushing people to use unions instead of transmutes.

So I propose we stabilize transmute in const, but not const fn. However, currently our handling of intrinsics in const-qualif is somewhat broken, so that should be fixed first.

See https://github.com/rust-lang/rust/pull/64011 for stabilizing transmute inside const but not const fn.

Is there any news about the stabilization?

@WaffleLapkin: @oli-obk reopened #64011 today because it got unblocked, then closed it again because apparently stabilizing transmute inside const but not const fn is no longer feasible.

So I think this is now blocked on union accesses in const fn being stabilized (#51909). I don't really understand the path forward for that one based on its comments.

Should we give this another try? Not much progress has been made on the unconst side of things (also see here), but allowing transmute where we already allow union could help get rid of a lot of nasty union-type-punning code (probably half of which is wrong because it forgets to add repr(C) to the union).

I'm creating a new stabilization PR to show the workarounds needed to allow such a split. We can then decide whether we'll take on that technical debt.

Was this page helpful?
0 / 5 - 0 ratings