-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Clarify behviour when writing to a union field that implements Drop #1663
Conversation
itself, though Rust code may explicitly implement Drop for a union type. | ||
the `Drop` trait. The explanation for that lint should include an explanation | ||
of the caveat documented in the section "Writing fields". The compiler may | ||
optionally provide a pragma to disable that lint, for code that intentionally |
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 think this should be fully specified one way or the other. And, nit, we don't usually use the terminology 'pragma'.
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.
What do you mean by "fully specified"?
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 assume this means s/may optionally/should/ here.
It would be helpful if you could summarise the discussion from the tracking issue which led to the decision in this RFC, thanks! |
Make it a "should" rather than a "may optionally", and name it.
…Drop Summarize (and link to) the discussion in the tracking issue.
@nrc Done. |
This RFC PR was discussed (briefly) in the lang team meeting and is now 🔔 entering the final comment period 🔔. |
union Union {
string: String,
vec: Vec<u32>,
}
let mut x: Union;
x = Union { string: "".to_owned() };
x = Union { vec: vec![] };
// both of these are assigning to mutable lvalues of type Union
// in the second case, this is equivalent to
// `drop_in_place(&mut x); write(&mut x, Union { vec: vec![] });`
// this doesn't run any drop glue, because Union doesn't inherit
// drop glue from it's internal members (Union only has drop glue
// if it literally impls Drop)
// however
x.vec = vec![];
// in this case you're assigning to an lvalue of type Vec<u32>
// which is equivalent to `drop_in_place(&mut x.vec); write(&mut x.vec, vec![])`
// which obviously drops the vector Basically, what I'm saying is, 👍 to this change :) |
I'm in favor of this specification. It's a subtle issue, but I agree with the conclusion of the earlier discussion that on the whole, this RFC's behavior provides the greatest degree of consistency. The use of a lint to alert users of the potential footgun here is very good; I expect we won't use many unions with |
Huzzah! The @rust-lang/lang team has decided to accept this RFC. |
Discussion in the tracking issue for unions turned up a corner case not addressed by RFC1444: whether assigning to a union field that implements
Drop
should drop the previous value of the field. Based on that discussion, document that such an assignment does drop the previous value of the field. Also document how to work around that if needed, and add a note that the lint warning for declaring a union field with a type implementingDrop
should explicitly document this issue in its explanation.