Tracking Issue for const `mem::discriminant`
lcnr opened this issue ยท 15 comments
The intrinsic is already implemented in Miri, you can copy that to rustc if you want.
If you do, please also submit a PR to Miri to remove the implementation there.
Should we consider adding more symbol kinds to const eval (like the way pointers can't be read as bits) to ensure that this feature isn't used to read discriminants as integers? Or is doing so at compile time actually something that enables legit use cases?
What we do for pointers is born out of necessity, and causes pain throughout the engine.
For discriminants (a) I cannot think of a practical way to do so, and (b) I view this the same as layout details: it is not UB to use raw pointers to observe and mess with repr(Rust)
layout if you get it right, but layout might change any time so you have no way to be sure that whatever is right for current Rust will remain right in the future.
Would this be to prevent something like this (which may break due to compiler updates)?
#![feature(core_intrinsics, const_discriminant)]
const ARR: [u32; std::intrinsics::discriminant_value(&Some(7)) as usize] = [42];
@lcnr we already have that with things like
const ARR: [u32; mem::size_of::<Option<Option<bool>>> = [42];
It seems that mem::discriminant
is now const, as the doc shows. Shouldn't this issue be closed?
@stephanemagnenat the const part of it is still unstable.
rust/library/core/src/mem/mod.rs
Lines 1014 to 1018 in d95745e
If you view nightly docs, it is much clearer, showing (const: unstable)
next to the function. It will take a couple of releases before that rustdoc feature is part of stable docs.
Thank you for the clarification!
Btw, I saw on the PR (#69825) that people were asking for use cases to decide whether to stabilise this feature. I believe I have such a use case: I am making a parser for a DSL that must match existing data structures, and these can have members of various types. I thus have a custom Value
type, and would like these data structures to return a description of themselves that contains which variant of Value
they accept. I was planning to use the Discriminant<Value>
type, but as I cannot have const values of this type in stable, I'll probably use the enum-kinds crate for now.
We have a similar issue in https://github.com/mapeditor/rs-tiled, so far we've resorted to creating a Tag
enum but using the discriminant would be much cleaner. One thing I'm unsure about though, is how to refer to the discriminant of a variant at compiletime without actually creating an instance of the enum.
One thing I'm unsure about though, is how to refer to the discriminant of a variant at compiletime without actually creating an instance of the enum.
I don't think that is possible. There is currently no work being done to allow this, and it's unclear to me how that could be done without making enum variants their own types that you can mention without needing a value
Maybe some kind of macro could do the job, like std::mem::discriminant_of!(Enum::Variant)
.
I'm not saying we can't add it, but that there are no plans for it. This issue is also the wrong place to figure out a design for it, so maybe open a thread on the internals forum?
We reviewed this in today's @rust-lang/lang meeting. It looks like there are mentions of wanting a use case to justify making this available in const
. Leaving aside that there appear to have been mentions of use cases, in general we feel that if a function exists as non-const and it can be written as const
then we should make it available in const
.
I have another use case (currently I ended up using the strum
and num_traits
packages), in addition to the one I mentioned on June 25 last year. I have a block-based visual programming language (see https://cand.li for a screenshot). Each block has possibly parameters (e.g. speed vector), and all blocks together are joined in a union. Sometimes, we want configurations where only a subset of blocks can be used (e.g. simple mode). It would be convenient to have such configurations const, so that they can be used in const contexts (as a global configuration for example). Ideally that feature would use the macro evoked by @aleokdev but even without it, there could be a const prototype for each block type (e.g. the one we show on the block palette) out of which the discriminant can be extracted in a const way.