Implement #[skip] for builtin derives#121053
Implement #[skip] for builtin derives#121053clubby789 wants to merge 3 commits intorust-lang:mainfrom
#[skip] for builtin derives#121053Conversation
|
That looks like a really useful shorthand! How does this interact with |
|
Hmm, good point. I think the simplest solution is to not emit the SPE impl if any fields are being skipped for PE? That would then match the behaviour of a custom PE impl |
71d0aa0 to
048a438
Compare
|
Given that this adds quite a bit of logic to deriving: |
This comment has been minimized.
This comment has been minimized.
Implement `#[skip]` for builtin derives Implement rust-lang#121050 Still needs some work but here's an initial working implementation to get feedback on the strategy.
|
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (6fc06e2): comparison URL. Overall result: ❌ regressions - no action neededBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 637.914s -> 640.063s (0.34%) |
|
Sorry for the delay ^^', I will try to review this in a few hours max and I will look into adding hygienic helper attributes. I wonder how hard it would be to implement an MVP. Maybe I can manage to mock a pre-RFC as well. No need to rebase btw, the long review time is entirely on me, sorry about that! |
| /// ### Explanation | ||
| /// | ||
| /// The `#[skip]` attribute allows ignoring a field during the derivation | ||
| /// of specific traits. This is not supported for other traits, e.g. it wouldd |
There was a problem hiding this comment.
| /// of specific traits. This is not supported for other traits, e.g. it wouldd | |
| /// of specific traits. This is not supported for other traits, e.g. it would |
| /// | ||
| /// The `#[skip]` attribute allows ignoring a field during the derivation | ||
| /// of specific traits. This is not supported for other traits, e.g. it wouldd | ||
| /// not be possible to clone a structure without cloning all fields.. |
There was a problem hiding this comment.
| /// not be possible to clone a structure without cloning all fields.. | |
| /// not be possible to clone a structure without cloning all fields. |
| if !skip_enabled { | ||
| rustc_session::parse::feature_err( | ||
| &cx.sess, | ||
| sym::derive_skip, | ||
| attr.span, | ||
| "the `#[skip]` attribute is experimental", | ||
| ) | ||
| .emit(); | ||
| } |
| let Some(skip_attr) = ast::Attribute::meta_kind(attr) else { | ||
| unreachable!() | ||
| }; |
There was a problem hiding this comment.
That's just .unwrap():
| let Some(skip_attr) = ast::Attribute::meta_kind(attr) else { | |
| unreachable!() | |
| }; | |
| let skip_attr = ast::Attribute::meta_kind(attr).unwrap(); |
| }; | ||
|
|
||
| // FIXME: better errors | ||
| match skip_attr { |
There was a problem hiding this comment.
Note: Ignoring the fact that the feature-gate error is already a breaking change, attribute validation of #[skip] emitting hard errors is also a breaking change.
| } | ||
|
|
||
| impl SkippedDerives { | ||
| pub fn add(&mut self, derive: Symbol) { |
| let mut exprs: Vec<_> = mk_exprs(i, struct_field, sp); | ||
| let self_expr = exprs.remove(0); | ||
| let other_selflike_exprs = exprs; | ||
| let mut skipped_derives = SkippedDerives::None; |
There was a problem hiding this comment.
Might want to move a lot of this code into a separate method to avoid rightward drift.
|
|
||
| // FIXME: better error for derives not supporting `skip` | ||
| // #[derive(Clone)] | ||
| // struct SkipClone(#[skip] usize); |
There was a problem hiding this comment.
If I understand the code correctly, we don't reject #[skip] (SkippedDerives::All) on unsupported traits at all contrary to #[skip(...)] (SkippedDerives::List) and end up generating non-sense code, right?
| // FIXME: better errors | ||
| match skip_attr { | ||
| ast::MetaItemKind::Word => { | ||
| skipped_derives = SkippedDerives::All; |
There was a problem hiding this comment.
If I understand correctly, this means we're not checking if #[skip] is supported by the current derive macro, right?
| const SUPPORTED_TRAITS: [Symbol; 5] = [ | ||
| sym::PartialEq, | ||
| sym::PartialOrd, | ||
| sym::Ord, | ||
| sym::Hash, | ||
| sym::Debug, | ||
| ]; |
There was a problem hiding this comment.
Not sure how I feel about hard-coding the list of supported traits. Technically speaking a built-in derive macro supports #[skip] if it declares skip as a helper attribute and conversely if it doesn't declare it then it doesn't support it. I wonder if we could somehow leverage this information (if it's available)?
|
I'm so sorry for letting you hanging like that. The fact that this T-libs-api feature likely requires involved language additions if we want to do it properly, paralyzed me. |
|
I'm gonna do a run crater to gather some data before doing anything else. |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment has been minimized.
This comment has been minimized.
|
@bors try |
Implement `#[skip]` for builtin derives Implement rust-lang#121050 Still needs some work but here's an initial working implementation to get feedback on the strategy.
|
☀️ Try build successful - checks-actions |
|
@craterbot check |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🎉 Experiment
|
|
Given the crater results showing compatibility hazards, it sounds like this is going to need a design and lang RFC for an approach that avoids those. Happy to work with anyone looking to write one. @fmease? |
Implement #121050
Still needs some work but here's an initial working implementation to get feedback on the strategy.
ACP: rust-lang/libs-team#334