-
Notifications
You must be signed in to change notification settings - Fork 1.6k
RFC: Allow #[ignore(Trait)]
on field to ignore it when deriving Trait
#3869
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
base: master
Are you sure you want to change the base?
Conversation
This can and should probably be an ACP, not an RFC. CC rust-lang/libs-team#334 from >1 year ago which proposed something very similar for Similarly, starting to interpret your proposed (We got away with the addition of |
Published it as an RFC that is what was suggested in this comment Validation: The following doesn't compile due to a deny-by-default future incompatibility lint which is going to be promoted to a hard error as part of this RFC: use derive as ignore;
struct Foo {
// syntax that will gain meaning because of this RFC
#[ignore()]
hello: ()
} This does not compile because of ambiguity. Whereas if use derive as ignore;
struct Foo {
#[ignore]
hello: ()
} So then giving this meaning should be fine: use derive as ignore;
struct Foo {
#[ignore(Foo, Bar)]
hello: ()
} struct Foo {
#[ignore(Foo, Bar)]
hello: ()
} Because it would not have compiled (without turning off the deny-by-default lint which says that we will promote it into a hard error in the future) This currently does compile, with a warn-by-default lint. And in the RFC I'll clarify that this will continue to compile, and its meaning will not be changed. struct Foo {
#[ignore]
hello: ()
} I'm not super familiar with terminology, but this isn't a new helper attribute - it's the same attribute Summary: If any other name was chosen, then it could be potentially breaking. But because If there are any possible breaking changes that I've missed, I would appreciate an example |
Ah, I completely forgot that Still, it would "need to become" a helper attribute but that would clash with the built-in attribute, or rather the built-in attribute However, I'm not an expert in those resolution rules, so maybe it's a non-issue, so I'm happy to be corrected by someone more knowledgeable. I'm wondering if we can properly discern helper and built-in attribute |
CC https://rust-lang.zulipchat.com/#narrow/channel/213817-t-lang/topic/namespacing.20macro.20attrs.20to.20reduce.20conflicts.20with.20new.20adds/ (from Jul–Sep '25) (don't quite remember if this is only tangentially related or indeed fully) |
Notes: | ||
|
||
- Fields can be either named or unnamed. | ||
- When applied to fields, `#[ignore]` takes a list of [`SimplePath`](https://doc.rust-lang.org/reference/paths.html#simple-paths)s separated by comma, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should let #[ignore(MyDerive)]
take arguments since some derives need to know how to produce an ignored field,
e.g. clap::Parser
uses #[arg(skip = <expr>)
to fill in that field with <expr>
when parsing your struct
from the command line.
I suggest:
#[derive(MyTrait)]
struct S {
#[ignore(MyTrait(<args>))] // <args> is any token stream
foo: Foo,
#[ignore(MyTrait)]
bar: Bar,
#[ignore(MyTrait = <arg>)] // <arg> is any expression
baz: Baz,
}
which gives the following input to MyTrait
's derive:
struct S {
#[ignore(<args>)]
foo: Foo,
#[ignore]
bar: Bar,
#[ignore = <arg>]
baz: Baz,
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not saying that I've thought of all possibilities, but that feels like a case where default field values would be a better solution to arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
arguments also let you write stuff like:
#[derive(Serialize)]
struct MyStruct {
#[ignore(Serialize(if self.name_is_meaningless()))]
name: String,
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but that's not really "ignoring" the field; it's adding a condition to serialisation. I would rather not overload the meaning of the attribute too much.
In the case of constructing the object, you're right that you can't ignore the field, and thus need something to put in its place. Default values solve that. Conditional serialization isn't really ignoring; it's just changing what the trait does to the field, if that makes sense.
Co-authored-by: Jacob Lifshay <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really elegant solution with transforming #[ignore(Xyz)]
-> #[ignore]
!
This RFC proposes that the
#[ignore]
attribute can now be applied to fields.Its purpose is to tell derive macros to ignore the field when generating code.
For the above struct
User
, derivesPartialEq
andHash
will ignore thename
andage
fileds.Code like this is generated:
Rendered