-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Allow custom derives for unions #50223
Comments
Most derives are not expecting a union. Moreover, how useful would any derive be in isolation if you need an external value to tell which field is valid data? The only derived traits I can see being useful are Maybe |
I don't see the problem with this? If a custom derive doesn't expect a union, it can simply fail.
These are all builtin derives. |
After a brief investigation, it is tempting to say that this might be a one-line change. The linked snippet is a last-minute check on the item kind just moments before expanding the macro. (It is, of course, the check that produces this error message.) Since custom derives are allowed to expand to arbitrary items, I can't imagine that there are any other diagnostics hiding around the corner anywhere that might be attempting to match this against a struct or enum. (But I'm still paranoid about it because if there is one, it'll probably give an ugly ICE if not updated) |
If builtin derives are already allowed on unions then it's a discrepancy not to allow custom derives. I do agree that it likely just requires lifting that check in the line you linked. |
The use case seems to be
So why not use a proc macro here? They'll get stable soon if we are lucky. |
@est31 why not use a proc macro in place of every custom derive? Same answer -- derive attributes look better and don't prevent code parsing tools like rustfmt from seeing the item. As for custom derives not expecting a union, it seems that at least syn is already equipped for this. |
I hope you do agree that #[repr(C)]
#[derive(MakeSureTraitIsImplemented)]
union Value {
a: u64,
b: f64,
} does not look better than #[repr(C)]
#[make_sure_trait_is_implemented]
union Value {
a: u64,
b: f64,
} I've meant the attribute proc macros, not the bang proc macros. Still, the derive macros were introduced, are taught, are being extended, and have a syntax that points to their actual purpose: deriving traits for structs. Any other use is --technically-- abuse of the feature. The only use case of this feature that I'm aware of is what @h2so5 mentioned in the thread linked: they wanted to make sure that every variant of the union implemented a trait. This is a solid use case, but it still is abusing the derive feature. @abonander pointed out correctly that If you are adding a feature where the only reasonable use case is its abuse, I think you've done a mistake in language design. I'm saying that as someone who loves abusing language quirks. |
Attribute proc macro makes more sense than bang proc macro here, yeah. I
think there are legitimate uses for derive on unions though, even this
isn't one of them.
…On Thu, Apr 26, 2018 at 1:20 PM, est31 ***@***.***> wrote:
derive attributes look better
I hope you do agree that
#[repr(C)]
#[derive(MakeSureTraitIsImplemented)]union Value {
a: u64,
b: f64,
}
*does not* look better than
#[repr(C)]
#[make_sure_trait_is_implemented]union Value {
a: u64,
b: f64,
}
I've meant the attribute proc macros, not the bang proc macros.
Still, the derive macros were introduced, are taught, are being extended
<rust-lang/rfcs#2385>, and have a syntax that
points to their actual purpose: deriving traits for structs. Any other use
is --technically-- abuse of the feature.
The only use case of this feature that I'm aware of is what @h2so5
<https://github.com/h2so5> mentioned in the thread linked: they wanted to
make sure that every variant of the union implemented a trait. This is a
solid use case, but it still is abusing the derive feature.
@abonander <https://github.com/abonander> pointed out correctly that Clone
and Copy are the only two traits that you can safely derive for unions,
and even then you can only derive Clone if it also implements Copy
(because obviously you can't dispatch).
If you are adding a feature where the only reasonable use case is its
abuse, I think you've done a mistake in language design. I'm saying that as
someone who *loves* abusing language quirks.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#50223 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAC3n0gWLIFs5CgAgp6yJxYbJC5XyIU2ks5tsgHpgaJpZM4Tjerr>
.
|
There are legitimate use cases.
|
@est31 Custom marker traits for union make sense when we want to ensure the characteristics of its memory block independent of the type of variant. For example:
|
This appears to be an E-Easy change and I'm willing to mentor. If everyone concurs I'll post mentoring instructions. |
All of the arguments against derive on unions so far also work as arguments against letting users handwrite trait implementations for their unions. Given that we already permit builtin derives on unions, and given that we allow users to handwrite trait implementations for a union type, I believe custom derive needs to be supported. |
Sure, go with it. I don't feel too strongly about it. |
@abonander I'd like to take care of this one as my first contribution to Rust once the mentoring instructions go up. |
@stevepentland It should be as simple as adding Of course you'll need to implement a test derive, which would involve adding two files to // aux-build:derive-filename.rs
// ignore-stage1 And you import it with The derive itself can be as simple as asserting the contents of the input and outputting nothing ( Don't forget the license headers, of course. You can copy them from one of the other files in the directory. To test it, run I don't have reviewer permissions so someone else will review the PR when you submit it, possibly @dtolnay or @petrochenkov or maybe someone else. Feel free to @-mention me though if you want me to look it over. |
The Union item type has been included in the allowed types for a custom derive. Closes rust-lang#50223
Add ability to apply custom derive to union types. The Union item type has been included in the allowed types for a custom derive. fyi @abonander Closes #50223
Derived from this question:
https://users.rust-lang.org/t/why-are-proc-macro-derives-prohibited-for-unions/17065
Currently, we cannot apply custom derives to unions:
This restriction should be removed if there is no technical issue.
The text was updated successfully, but these errors were encountered: