Proposal: require noreturn
as backing/tag of uninstantiable enum
#19855
Labels
Milestone
noreturn
as backing/tag of uninstantiable enum
#19855
Empty-AND-exhaustive
enum
-s are uninstantiable ("noreturn
-like") types - see #3257, #15909, and other issues for explanation.In status-quo (tested
0.13.0-dev.46+3648d7df1
), the compiler choosesu0
as the backing/tag type ofenum{}
.While that is not distinctly wrong, this is the same backing/tag type as chosen for an exhaustive
enum
with one value,enum{foo}
.Via manual override the compiler actually allows you to choose any integer type as the backing/tag of an uninstantiable
enum
.When using a non-zero-bit type, as fields they even participate in the size of the containing aggregate, even though they are uninstantiable,
which I believe to be nonsensical behavior, and potentially a bit confusing:
I propose that instead, an uninstantiable
enum
should always have a tag type ofnoreturn
(whether explicitly specified or compiler-deduced),
which should make its nature more clear to all parties.
When manually writing an uninstantiable
enum
type, the tag/backing type specified in status-quo is virtually meaningless.Still having an integer type specified may confuse readers -
and the only reason I could think of doing this would be if the writer intended the
enum
with an instantiable backing/tag type to be instantiable.The proposal instead turns this into a compile error, clearly stating that the backing/tag type needs to change to
noreturn
, the enum needs at least one state/field, or to be made non-exhaustive.As another small benefit, it becomes easier to account for the possibility of uninstantiable
enum
types in userland reflection code.Where today it might use the backing/tag 's bit size in calculation, like the compiler does in status-quo,
noreturn
isn't an integer type, so will trigger a compile error directly pointing to where logic needs to diverge.Code that deals with this in status-quo needs to special-case based on the enum having no fields AND being exhaustive,
which is more complex and leads to less uniform code.
EDIT: Note that non-exhaustive
enum
-s already require specifying a backing/tag type in status-quo (f.e.enum{_}
leads to a compile error).Further, because
_
already checks that there are unused state/field values left (enum(u1){a,b,_}
errors due to this),it seems the most regular to disallow
enum(noreturn){_}
as well - there is no value for_
to represent.The text was updated successfully, but these errors were encountered: