Request: derive enum's default

Hello,

AFAICS, for enum-types a statement like “#[dervive(Default)]” is not supported, instead developer has got to go the long way, implementing the Default-trait manually for the enum-type/variant in question.

I would like to see, if the Rust compiler would support some kind of annotation, marking the default variant of the enum-type in question.

Please let me know if this has been discussed in the past already.

There might be different solutions/syntax to achieve this, I would prefer to annotate the variant the following way, marking the specific variant with “#[default]”:

#[derive(Default)]
enum Kind {
   #[default] 
   A,
   B(i32),
   C,
}

This marking would also ease the reading/understanding of the enum-type.

Any comments are welcome.

1 Like

derivative can do that.

smart-default as well.

That said, at a minimum, #[default] to mark a default enum variant does seem to be the obvious kind of behavior that it’d be nice for std to support.

I have an RFC draft proposing #[default] on enum variants + default field values… I’ll publish this eventually.

1 Like

Selecting default explicitly is more powerful, but I’m surprised that Default doesn’t “just work” by picking the first variant in the enum (and require it to support Default on all its values, if there are any).

@Centril RFC would be great :slight_smile:

@kornel Agree,using first element of enum-variant-list (without explicit #default statement) as default-value would be simple rule and easy to understand (AFAICS). Wondering, maybe not stable regarding refactoring of code (?)

As far as I remember, that’s exactly the official rationale for #[derive(Default)] not supporting enums. If you change the order of the variants, it would change the return value of the default impl, which is potentially (and very likely) breaking and otherwise error-prone anyway. Thus, selecting the default explicitly is the right thing to do.

3 Likes

Unfortunately that rationale is not applied consistently—the same is true for derive(PartialOrd), but that’s allowed.

4 Likes

Doesn’t this mean that PartialOrd derivation should be fixed instead of allowing more sloppiness in the language by means of Default? I know we technically can’t now because it’s breaking, I’m only referring to the principle.

1 Like

I’m one of those people that thinks it works as expected and I don’t consider it broken at all. If you want a particular ordering, manually implement the trait. Same for defaults: if you want a particular default, manually implement it. Otherwise, picking the first enum entry seems like a sane default to me.

2 Likes

Just as a straw man counter example: what if the logically smallest item isn’t the logical default? Say, music accidentals, {𝄫, ♭, ♮, ♯, 𝄪}: they obviously sort in this order, low to high, but the middle is also obviously the default.

Of course we can just implement default manually, but I don’t think it uncommon that the logically first is not the logical default; rather, the logical middle often is.

2 Likes

Manually implementing Default is a lot simpler than manually implementing Ord, so favouring deriving Ord is probably reasonable.

In my opinion, a derive doesn't always have to do the semantically correct thing - it can't know what that is, but doing a simple to understand, often desirable thing seems like a reasonable default.

2 Likes

It's not technically "broken", but it's still error-prone. It's unfortunate enough that simple, intuitively insignificant refactoring (an enum is a disjoint sum, and addition ought to be commutative, so the order of variants shouldn't matter!) of an enum with #[derive(PartialOrd)] leads to a potentially breaking change. And unlike manually specifying the entire ordering (which definitely doesn't scale), a single #[default] annotation is not a burden at all (sorry, I just don't buy that it is); rather, it's trivial.

Correctness is not just about staying technically memory-safe; it's a lot more, and when we have the opportunity to prevent programmers from shooting themselves in the foot, we should use that opportunity wisely.

3 Likes

@Centril did you have time to file the RFC for the '#[default]' feature?

I'm rather swamped right now, but I will try to make some progress on the RFC in the coming 2 weeks. In my RFC #[default] is a part of a larger whole and the whole needs some adjustment. However, please note that this RFC would not be a roadmap priority and the language team (of which I'm a part) has a large backlog so it will take time to get to the RFC once filed.

@centril great, please let me know if I can help out

1 Like