-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#[derive(Default)]
on enums with a #[default]
attribute
#3107
Conversation
This comment has been minimized.
This comment has been minimized.
Error: This repository is not enabled to use triagebot. Please let |
I strongly disagree with the |
If the type itself is not used directly, but rather through some other type (like the example of As to Keep in mind that this RFC is intentionally minimal such that |
This comment has been minimized.
This comment has been minimized.
If I understand the design as specified, I don't have a good suggestion to solve this. (A wild suggestion: make it possible to put |
Having derives on enum variants themselves just feels wrong to me, given that enum variants are not types in and of themselves (I'm aware of the RFC changing that). |
I think this part is sufficiently clear that it's impermissible:
The "iff" indicates that it's all or nothing. |
please don't use "iff", that's a very jargon-y variant of the word that honestly looks like a typo to most people. |
@Lokathor It's not uncommon to see that term in technical writing, which this is. I'd agree if it were not in the reference-level explanation. |
Please expand it out to "if and only if" even in the reference. I would have thought that was a typo even though I have seen "iff" before, but only in a mathematical logic setting, not usually in a programming language reference. |
bf0196b
to
bae1c39
Compare
Changed to write it out. |
bae1c39
to
d5757c9
Compare
Browser ate my comment and I don't feel like writing it up again so basically I think it would be better if there wasn't any special handling based upon what variant you mark as the default, or whether it's marked as non-exhaustive, and always just puts bounds on the generics like the default struct logic does. |
@clarfonthey The bounds were widely discussed on the linked IRLO post. The overwhelming majority of people did not want that behavior. There is also a legitimate concern regarding forward-compatibility for |
@jhpratt as I said, I had initially typed up said discussion, but my browser ate the text, and I've already been having a pretty bad day and that's why I decided to simply clarify what my original objection was (since that seemed rather unclear) without retyping the whole argument. I have a strong feeling that you're arguing in good faith and just want a properly focused discussion, but having an ounce of empathy would be nice. FWIW the entire RFC process is supposed to bring people into the discussion who otherwise might not have been in those earlier discussions. Part of that discussion can just be people stating their feelings on the proposal itself without fully elaborating, as people with more time and energy will likely be able to help fully work out those points. In other words: simply telling people off for not fully elaborating their points is rude and unwelcome, especially when they give explicit reasons for not fully elaborating their points. I know that working on an RFC is hard work, and I actually was the person who wrote the original |
Sorry if I'm missing something, but I'm a bit confused about the bound behavior. What is the generated bound on the following? #[derive(Default)]
enum A<T> {
#[default]
A(Option<T>);
} Is it
Based on this, it sounds like the latter. If so: this is different than how structs currently behave. There is a longstanding issue here with over 100 comments, and I feel this RFC should mention the issue and explain why the concerns raised there don't apply here. |
It would be Edit: Here's my thoughts after quickly looking through that thread. This comment doesn't apply because everything in The only other issue I see is the possibility of having a recursive enum (boxed of course), which should be trivially solvable by just not including that exact type in the bound, no? |
@clarfonthey I was not telling you off in any way. I was simply stating that your comment as worded didn't contribute much, as there was already a decent discussion on IRLO (which was intended to be used as a reference as to some reasoning). In my opinion, just stating "I don't like this" doesn't really give me anything to work with, as I'm sure you can understand. If this is just you having a bad day, I'd like to kindly suggest sleeping on it. Sometimes that makes a world's difference 🙂 |
Now that I've had a bit of rest, again elaborating my position: I don't think that the fact that enum fields are public should change how generic bounds are set. Today you can create a struct with entirely public fields and this still will not set bounds based upon fields, but the generics directly. (see example) Additionally, while it's tempting to only constrain bounds based upon the specific default chosen, this is technically uncharted territory. Normally, structs will be forced to still use generics even if they're marked as non_exhaustive, but in this particular case, you can sidestep using them for a single variant by using them on others. While I agree that this behaviour is natural and desirable in some form, it breaks the precedent we have for structs and may make the behaviour seem less predictable based upon context. This is what I was trying to say by breaking symmetry with structs, which I tried to elaborate before my browser crashed and ate my post. I think that it's definitely nice, but I'm not sure that it's as simple as the RFC is making it out to be. Plus, the other traits don't act this way either, e.g. |
If the primary concern being raised is that private fields exist (on structs), why shouldn't that difference be noteworthy?
This is widely regarded as incorrect, so why should we willfully repeat this mistake? I think it would be best to not do so and to try and fix the existing issues with bounds from other derives separately.
I'm not entirely sure what you're referring to here. This RFC doesn't change how generics are handled on the enum itself, which is different from how they work on structs to begin with (that's why you can have I'm not sure if you've had a chance to review the IRLO post or not (obviously fine if not!). There was a fair amount of discussion regarding bounds, and you will notice that I myself initially wanted the bounds to match the existing behavior of structs. I was convinced otherwise both due to the known erroneous bounds and an overwhelming opinion against my initial thoughts. |
Just to point out (not sure it's significant) - another case mentioned in the thread is this where it's a public type but its Default implementation depends on a private trait. Also, I think the cyclic case is a bit trickier than skipping recursive types, since it can also happen at the trait level. See here for example. I personally actually feel like the approach described in this RFC is better than the current derive behavior. I'm just raising this concern because it seems weird that Default would work differently for enums than any other standard derive macro (including Default for struct, and any other trait for enums). Ultimately I would like all traits to work as described, but I'm wondering if it makes sense to do it for this specific case when the issue in question has been open for so long without clear consensus. Edit: Just clarifying to avoid confusion - I believe that the concern I'm raising here is orthogonal to the question of whether bounds should be generated from all variants vs just the |
I feel like "widely regarded as incorrect" is a claim that requires a bit more evidence to be backed up. I feel like there's a lot of nuance to the decision and while I do think that the behaviour may be confusing or undesired at times, I don't think that it's explicitly bad. If we do want to change the behaviour of this, I think it would be 100% reasonable to discuss and do on a new edition (since derive behaviour is definitely something that can change between editions), but that's not what this RFC is about. IMHO, unless the goal is to completely overhaul the way derives are done rather than just adding an extra case for defaulting enums, we should just go with the existing behaviour to limit confusion. |
+1 for fixing derives!!! been having issues with |
May also be worth noting that https://crates.io/crates/num_enum has a So the |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
3996301
to
ee1e93c
Compare
Updated to match the fact that the |
RFC 3107: "`#[derive(Default)]` on enums with a `#[default]` attribute" (#3107).
…um, r=davidtwco Stabilize `derive_default_enum` This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](rust-lang/rfcs#3107) and tracked in rust-lang#87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility). `@rustbot` label +S-waiting-on-review +T-lang
…um, r=davidtwco Stabilize `derive_default_enum` This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](rust-lang/rfcs#3107) and tracked in rust-lang#87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility). ``@rustbot`` label +S-waiting-on-review +T-lang
…um, r=davidtwco Stabilize `derive_default_enum` This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](rust-lang/rfcs#3107) and tracked in rust-lang#87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility). ```@rustbot``` label +S-waiting-on-review +T-lang
…um, r=davidtwco Stabilize `derive_default_enum` This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](rust-lang/rfcs#3107) and tracked in rust-lang#87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility). ````@rustbot```` label +S-waiting-on-review +T-lang
…um, r=davidtwco Stabilize `derive_default_enum` This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](rust-lang/rfcs#3107) and tracked in rust-lang#87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility). `````@rustbot````` label +S-waiting-on-review +T-lang
…um, r=davidtwco Stabilize `derive_default_enum` This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](rust-lang/rfcs#3107) and tracked in rust-lang#87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility). ``````@rustbot`````` label +S-waiting-on-review +T-lang
…um, r=davidtwco Stabilize `derive_default_enum` This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](rust-lang/rfcs#3107) and tracked in rust-lang#87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility). ```````@rustbot``````` label +S-waiting-on-review +T-lang
…idtwco Stabilize `derive_default_enum` This stabilizes `#![feature(derive_default_enum)]`, as proposed in [RFC 3107](rust-lang/rfcs#3107) and tracked in #87517. In short, it permits you to `#[derive(Default)]` on `enum`s, indicating what the default should be by placing a `#[default]` attribute on the desired variant (which must be a unit variant in the interest of forward compatibility). ```````@rustbot``````` label +S-waiting-on-review +T-lang
Pre-RFC on IRLO
TLDR allow this:
Rendered