-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Implement #[skip]
for builtin derives
#121053
base: master
Are you sure you want to change the base?
Conversation
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! |
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.
Some initial thoughts.
/// ### 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// 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(); | ||
} |
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.
Note: Breaking change.
let Some(skip_attr) = ast::Attribute::meta_kind(attr) else { | ||
unreachable!() | ||
}; |
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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) { |
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.
simple yet beautiful ❤️
@@ -1532,11 +1579,76 @@ impl<'a> TraitDef<'a> { | |||
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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