-
Notifications
You must be signed in to change notification settings - Fork 540
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
base: master
Are you sure you want to change the base?
Conversation
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. |
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.
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
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] |
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.
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.
fixed_variable_drop_order(Ok([ | ||
PrintOnDrop("Dropped last"), | ||
PrintOnDrop("Dropped first"), | ||
])); | ||
|
||
fixed_variable_drop_order(Err([ | ||
PrintOnDrop("Dropped first"), | ||
PrintOnDrop("Dropped last"), | ||
])); |
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 feel like these examples would benefit from comments, but I haven't been able to come up with something concise enough yet.
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.