Skip to content

specify relative drop order of pattern bindings #1953

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dianne
Copy link

@dianne dianne commented Jul 30, 2025

Reference PR for rust-lang/rust#143764.

This replaces the unspecified destructors.scope.bindings.match-pattern-order with two new rules describing the run-time drop order of pattern bindings as of rust-lang/rust#143764. The included examples behave correctly on stable Rust as well.

If multiple patterns are used in the same arm for a `match` expression, then an
unspecified pattern will be used to determine the drop order.
r[destructors.scope.bindings.pattern-drop-order]
If a pattern binds multiple variables, they are dropped in reverse order of delcaration.
Copy link
Author

Choose a reason for hiding this comment

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

The order of "declaration" is left mostly unspecified, other than by destructors.scope.bindings.or-pattern-declaration-order below. I like specifying the order as the reverse of another order to better match the other rules around drop order, and "reverse declaration order" is used for this purpose in the FLS1. Other possible terms could be "reverse of source order", "reverse order of appearance", or "reverse order of first appearance" to combine the two rules. I don't think any of them read quite as well though.

Footnotes

  1. https://rust-lang.github.io/fls/ownership-and-deconstruction.html#drop-order

r[destructors.scope.bindings.match-pattern-order]
If multiple patterns are used in the same arm for a `match` expression, then an
unspecified pattern will be used to determine the drop order.
r[destructors.scope.bindings.pattern-drop-order]
Copy link
Author

Choose a reason for hiding this comment

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

This also only specifies the dynamic semantics of drops, not their static semantics; those seem to be handled by the Nomicon rather than the Reference. See e.g. rust-lang/rust#142057 for an instance where the static semantics would need additional specification. Or for (probably) a non-bug, consider an x @ Struct(y) pattern: x is declared before y, but y is bound before x and (incidentally, as an implementation detail) is considered potentially live until after x is dropped. This is to allow copying into y before moving into x. This can't affect the order in which destructors are run, since if they both had significant drops, neither would be Copy, and the match scrutinee can't be moved into both y and x. As far as I can tell, the only effect x being dropped first has is slightly more permissive drop-checking in edge cases where e.g. x is mutated to contain a reference to y.

Since the Reference only specifies when destructors are run, I've chosen to keep things simple and not handle any of that.

Comment on lines +220 to +228
fixed_variable_drop_order(Ok([
PrintOnDrop("Dropped last"),
PrintOnDrop("Dropped first"),
]));

fixed_variable_drop_order(Err([
PrintOnDrop("Dropped first"),
PrintOnDrop("Dropped last"),
]));
Copy link
Author

Choose a reason for hiding this comment

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

I feel like these examples would benefit from comments, but I haven't been able to come up with something concise enough yet.

@dianne dianne marked this pull request as ready for review July 30, 2025 11:41
@rustbot rustbot added the S-waiting-on-review Status: The marked PR is awaiting review from a maintainer label Jul 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: The marked PR is awaiting review from a maintainer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants