Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upAdd empty dropped variant to ManuallyDrop #49056
Conversation
rust-highfive
assigned
sfackler
Mar 15, 2018
This comment has been minimized.
This comment has been minimized.
|
r? @sfackler (rust_highfive has picked a reviewer for you, use r? to override) |
rust-highfive
added
the
S-waiting-on-review
label
Mar 15, 2018
This comment has been minimized.
This comment has been minimized.
|
Do we have to "assign" to .dropped in the drop method? Not sure what the semantics of unions are exactly. |
This comment has been minimized.
This comment has been minimized.
|
@sfackler I suppose you could |
This comment has been minimized.
This comment has been minimized.
|
cc #47650 @mikeyhew @nikomatsakis. This PR is going to invalidate the entire presumption of #47650, that |
This comment has been minimized.
This comment has been minimized.
|
An alternate interpretation for the |
This comment has been minimized.
This comment has been minimized.
|
But how could you construct an |
This comment has been minimized.
This comment has been minimized.
|
@sfackler If we went that route, we'd make it legal to construct any union by specifying either 0 or 1 field (rather than exactly one, as it is today). |
This comment has been minimized.
This comment has been minimized.
|
Ah sure |
This comment has been minimized.
This comment has been minimized.
|
@eddyb drew a distinction between |
This comment has been minimized.
This comment has been minimized.
|
@rkruppe I'm having a hard time understanding that distinction, since |
This comment has been minimized.
This comment has been minimized.
|
@cramertj See the discussion preceding the comment I linked. Kind of hard to tell where it starts but this #47650 (comment) might be a reasonably close starting point. But basically IIUC the argument goes that "initializing and then dropping" leaves some values intact and is therefore different from never having initialized at all. |
This comment has been minimized.
This comment has been minimized.
|
Yeah, I read that, and I'm unsure whether I agree or not :) While it is definitely the case that some types have a valid repr even after being dropped (like primitives or As I type this, I'm coming around to the idea more and more, however I'm having trouble formalizing it: the property is something like "a union contains data that is a valid bit-based representation of one of its variants, but does not necessarily enforce the type's usual invariants". For example, Because the same rules apply to But I also might be massively overcomplicating this-- perhaps this rule can be phrased in a way that has a much smaller scope than I'm imagining. |
This comment has been minimized.
This comment has been minimized.
|
After thinking about this more, I've convinced myself that any memory model we adopt would require that a value of type T which has had |
cramertj
closed this
Mar 16, 2018
This comment has been minimized.
This comment has been minimized.
Is this because I'm not really convinced by this line of argument, but it also doesn't seem obvious that the "usual rules" must apply to the And besides, your formulation doesn't really say anything about the validity of the value after drop glue has run on it. |
This comment has been minimized.
This comment has been minimized.
|
A bit off-topic, but one of the main reasons I want |
This comment has been minimized.
This comment has been minimized.
|
@rkruppe yeah, that's one of the main reasons. The other is that it allows me to make sense of the way unions are being used in @eddyb's preferred model-- that there's a differentiation between uninit and dropped T, whereas I had previously been considering both as just "not a |
This comment has been minimized.
This comment has been minimized.
|
I'm going to reopen this because there's a serious question here that has been left unanswered, and I think we should make some sort of a decision here before closing this (at least without a followup RFC or tracking issue). There are a few options:
|
cramertj
reopened this
Mar 16, 2018
This comment has been minimized.
This comment has been minimized.
|
With "enum interpretation" of unions |
This comment has been minimized.
This comment has been minimized.
|
@petrochenkov except that dropping a single-field union does not drop the field it contains, whereas dropping a single-field struct does. I think that's the only difference though, right? |
This comment has been minimized.
This comment has been minimized.
|
@cramertj thanks for posting this, I think it's important that we get a formal definition here before stabilizing unions with drop fields.
My understanding when opening #47650 was that one of these two statements was true. Is there a practical difference between them?
I think this is a typo, do you mean "uninitialized"? |
This comment has been minimized.
This comment has been minimized.
It's primarily an issue of how to define things, specifically what it means for a value to have type
Yup, fixed. |
This comment has been minimized.
This comment has been minimized.
|
My personal expectation so far was that adding an empty variant to a union is pretty much a NOP. I imagined unions would be "barriers" to type validity; the compiler would never assume anything "for free" about data below a union (just like it never assumes anything "for free" for data below an In particular, I expected that a union with a The main reason for this is simplicity and consistency. If we decide that the contents of unions can matter, there are just so many questions to answer. Are single-field unions special? Or is a union with three fields, all of which are I have to admit I don't fully understand @eddyb's reasoning in the other thread, in particular the part at #47650 (comment) is entirely lost on me. If someone could explain why making unions "ignore" the valid bit-patterns of their inner types is a bad idea, that'd be appreciated. :) Is it "just" the layout-based optimizations?
New typestates seem to crop up everywhere recently. ;)
They would not necessarily invalid, it all depends on which requirements we make for that "typestate". I see variant 2 as a special case of variant 1. Also, just reading uninitialized data is fine, so I can't actually think of any reasonable optimization that could be invalidated. Could you give an example? At some point on IRC I've been talking with @eddyb about the contract for Either way, I imagine even an unsafe type has very little freedom in picking its "dropped" invariant. In fact, I think it is always fully determined structurally; is there any utility in types being able to still have private invariants in this state? Also, may I add "variant 4": The value inside the union can be anything. That's what I described above. The "completely dropped" typestate would then always have the trivial invariant that does not assume anything. |
This comment has been minimized.
This comment has been minimized.
To clarify, I think your interpretation is this option:
in my comment above, right? |
This comment has been minimized.
This comment has been minimized.
|
Ah, yes. I read that but then forgot about it when replying... sorry. Yes, that is "variant 4". |
This comment has been minimized.
This comment has been minimized.
|
I don't think there was consensus. Also see #47650 (comment). Essentially, I think we need an RFC to decide the situation around single-variant and/or unsized unions. Also, I wrote
|
This comment has been minimized.
This comment has been minimized.
|
I agree there was no consensus reached. One of my to do items I have yet to act upon is trying to spin up some more regular unsafe guidelines meetings. Seems like it would be good to circle back on this point. |
This comment has been minimized.
This comment has been minimized.
|
Ping from triage! What's the status of this PR? |
This comment has been minimized.
This comment has been minimized.
|
This is now on the unsafe code guidelines agenda: https://internals.rust-lang.org/t/proposal-reboot-the-unsafe-code-guidelines-team-as-a-working-group/7307 |
pietroalbini
added
S-blocked
and removed
S-waiting-on-review
labels
Apr 23, 2018
This comment has been minimized.
This comment has been minimized.
|
Marking this as blocked on some consensus from the unsafe guidelines WG. |
kennytm
added
the
I-needs-decision
label
Apr 24, 2018
shepmaster
added
S-blocked
and removed
S-blocked
labels
May 6, 2018
pietroalbini
added
S-blocked
and removed
S-blocked
labels
May 14, 2018
TimNN
added
S-blocked
and removed
S-blocked
labels
May 22, 2018
pietroalbini
added
S-blocked
and removed
S-blocked
labels
Jun 4, 2018
TimNN
added
A-allocators
and removed
A-allocators
labels
Jun 12, 2018
TimNN
added
A-allocators
S-blocked
and removed
A-allocators
S-blocked
labels
Jun 26, 2018
This comment has been minimized.
This comment has been minimized.
|
Closing until some consensus is reached by the unsafe guidelines WG. |
pietroalbini
closed this
Jul 14, 2018
pietroalbini
added
S-blocked-closed
and removed
S-blocked
labels
Jul 14, 2018
This comment has been minimized.
This comment has been minimized.
|
For future reference, I think I now actually understood #49056 (comment): (Quoting from #51361 (comment))
As @eddyb remarked, |
This comment has been minimized.
This comment has been minimized.
|
I think we should not do this, see https://internals.rust-lang.org/t/pre-rfc-unions-drop-types-and-manuallydrop/8025 for further details. This actually side-steps having unsafe code guidelines involved by making |
cramertj
deleted the
cramertj:sound-manually-drop
branch
Jul 23, 2018
This comment has been minimized.
This comment has been minimized.
|
|
cramertj commentedMar 15, 2018
Change
ManuallyDrop's internal (unstable) representation to match the design ofMaybeUninitin rust-lang/rfcs#1892. This indicates that the union has more than one possible representation variant. After the inner type has been dropped, it is no longer a validT, and so the union should be considered to contain only().cc @canndrew @RalfJung