Skip to content
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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

clubby789
Copy link
Contributor

Implement #121050

Still needs some work but here's an initial working implementation to get feedback on the strategy.

@rustbot
Copy link
Collaborator

rustbot commented Feb 13, 2024

r? @fmease

rustbot has assigned @fmease.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Feb 13, 2024
@juntyr
Copy link
Contributor

juntyr commented Feb 14, 2024

That looks like a really useful shorthand!

How does this interact with StructuralPartialEq?

@clubby789
Copy link
Contributor Author

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

@clubby789
Copy link
Contributor Author

Given that this adds quite a bit of logic to deriving:
@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Feb 16, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 16, 2024
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.
@bors
Copy link
Contributor

bors commented Feb 16, 2024

⌛ Trying commit 048a438 with merge 6fc06e2...

@bors
Copy link
Contributor

bors commented Feb 16, 2024

☀️ Try build successful - checks-actions
Build commit: 6fc06e2 (6fc06e29295186c2692d3d62a5c2062e584423f2)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (6fc06e2): comparison URL.

Overall result: ❌ regressions - no action needed

Benchmarking 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
@rustbot label: -S-waiting-on-perf -perf-regression

Instruction count

This is a highly reliable metric that was used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
3.6% [0.4%, 6.8%] 2
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Max RSS (memory usage)

Results

This 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.

mean range count
Regressions ❌
(primary)
2.7% [2.7%, 2.7%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-3.1% [-3.1%, -3.1%] 1
All ❌✅ (primary) 2.7% [2.7%, 2.7%] 1

Cycles

Results

This 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.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
4.6% [4.6%, 4.6%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 637.914s -> 640.063s (0.34%)
Artifact size: 306.33 MiB -> 306.36 MiB (0.01%)

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Feb 16, 2024
@fmease
Copy link
Member

fmease commented Mar 22, 2024

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!

Copy link
Member

@fmease fmease left a 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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..
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// not be possible to clone a structure without cloning all fields..
/// not be possible to clone a structure without cloning all fields.

Comment on lines +1586 to +1595
if !skip_enabled {
rustc_session::parse::feature_err(
&cx.sess,
sym::derive_skip,
attr.span,
"the `#[skip]` attribute is experimental",
)
.emit();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Breaking change.

Comment on lines +1595 to +1598
let Some(skip_attr) = ast::Attribute::meta_kind(attr) else {
unreachable!()
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's just .unwrap():

Suggested change
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 {
Copy link
Member

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) {
Copy link
Member

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;
Copy link
Member

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);
Copy link
Member

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;
Copy link
Member

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?

Comment on lines +1620 to +1627
const SUPPORTED_TRAITS: [Symbol; 5] = [
sym::PartialEq,
sym::PartialOrd,
sym::Ord,
sym::Hash,
sym::Debug,
];
Copy link
Member

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)?

@fmease
Copy link
Member

fmease commented Apr 24, 2024

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.

@fmease
Copy link
Member

fmease commented Apr 24, 2024

I'm gonna do a run crater to gather some data before doing anything else.

@fmease

This comment was marked as resolved.

@bors

This comment was marked as resolved.

@rust-log-analyzer

This comment was marked as resolved.

@rust-log-analyzer

This comment has been minimized.

@fmease
Copy link
Member

fmease commented Apr 24, 2024

@bors try

@bors
Copy link
Contributor

bors commented Apr 24, 2024

⌛ Trying commit 93300c6 with merge 0d3c0c4...

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 24, 2024
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.
@bors
Copy link
Contributor

bors commented Apr 24, 2024

☀️ Try build successful - checks-actions
Build commit: 0d3c0c4 (0d3c0c4551bd9d6b6a4bd51e251b596e0195adf5)

@fmease
Copy link
Member

fmease commented Apr 24, 2024

@craterbot check

@craterbot
Copy link
Collaborator

👌 Experiment pr-121053 created and queued.
🤖 Automatically detected try build 0d3c0c4
🔍 You can check out the queue and this experiment's details.

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-crater Status: Waiting on a crater run to be completed. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 24, 2024
@craterbot
Copy link
Collaborator

🚧 Experiment pr-121053 is now running

ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot
Copy link
Collaborator

🎉 Experiment pr-121053 is completed!
📊 13 regressed and 2 fixed (442198 total)
📰 Open the full report.

⚠️ If you notice any spurious failure please add them to the blacklist!
ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more

@craterbot craterbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-crater Status: Waiting on a crater run to be completed. labels Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants