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 up
Use normal mutable borrows in matches #57609
The following additional changes are made to accommodate
There is some further clean up done in this PR:
added a commit
this pull request
Jan 14, 2019
A bit of a longer write up on the two options here then.
CFG construction changes
For reference, the generated CFG for a match with 3 arms where the first one has a guard now looks something like this:
Fake borrows changes
Fake borrows are now added not only to the start block, but also to the end of any binding block that are proceeded by a guard. This means that the fake borrows are not live for the binding block and so do not conflict with any
Option A (commit 1)
At this point using minimal two-phase borrows is compatible with the match lowering. Some notes:
Option B (commit 3)
This uses real borrows. See OP for some details. Some note:
@matthewjasper ok, I read your comment, but I still feel like I don't fully understand what is being proposed. Probably I'm just missing a certain amount of context. Let me just pepper out a few questions I guess:
When you say "fake borrows", you mean that we put dummy borrows like
Why does it mean that? Because the "fake borrows" we inserted at the start block never wind up being used? Are they live only during the matching code that we generate, which inspects the discriminants and so forth, or are they ever live for "user code" (i.e., guards)? If they are only live for code we generate, then it doesn't seem like they play much of a role, do they? (Since we trust that code not to mutate things.) Maybe they are needed for initialization checks or something?
What is a "minimal" 2PB? And which borrows are becoming 2PB exactly? Do you mean for the
I feel like what I might like to see is some kind "representative desugaring" of a match in both styles.
A simple example of the generated MIR for nightly and for this branch is here https://gist.github.com/matthewjasper/fb0f4bfb9d3a6d179ed0c2eb7a5b0da5 I've marked the 2-phase borrow that's created on nightly.
Yes. In the example above, all of the shallow/guard borrows are "fake borrows". See
They're live in all guards (and while we're branching). They're not live outside of the match expression, in the arm expressions or after we've selected a pattern and are creating bindings for it - either the bindings for the guard or the bindings for the arm.
I mean the version of 2 phase borrows discussed in #56254. The two-phase borrows are the ones that are already two phase: the borrows associated to
Jan 19, 2019
referenced this pull request
Jan 21, 2019
OK, I read the desugared example in your gist. Allow me to attempt to re-summarize what is going on.
First off, the match process looks vaguely like this:
Does this sound right?
To redraw my flow graph with fake borrows inserted, it looks something like this:
If that is the case, I am wondering what the role of the fake borrows being live during "discriminant testing" is. I don't think they're harmful per se, just trying to create an accurate model of what the "threats" are.
I think there are a few things that users can do that are problematic:
So, first a couple of my own versions of the diagram:
In the case of no guard
No, there's no read here at the moment (you link to a fake read at (***)). It would certainly be nicer to have them there instead of where they currently are if it's not too annoying to implement. Currently we rely on the
As well as the above I think you're asking why
If there's no guard then