-
Notifications
You must be signed in to change notification settings - Fork 13.3k
NLL: refine liveness with "maybe initialized" analysis #45665
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
Comments
We should have the right sort of data in |
Let me leave some notes on how things work now. I've been digging about in the code a bit to get a better understanding of what's going to be required here. The NLL code approaches things just a hair differently from the existing borrowck data-flow operator, but I think the two should match up well enough. First, a bit of background. In order to track which paths are moved etc, we currently construct up a tree of paths. Each such path is called a The move paths are arranged in a tree, so e.g. if you have a move path It is instructive to look at where In order to detect the case where rust/src/librustc_mir/borrow_check.rs Lines 737 to 743 in 9f3b091
First, it looks for a move-path for |
Initial mentoring instructions: step 1First, we are going to have to do a bit of surgery to the current control-flow, I think. Right now, the borrowck begins by invoking Probably, also, it would be useful to make Next, I think what we really want is to split up the
OK, ran out of time, will write more later! |
I'm taking this one 😄 |
@Nashenas88 wound up doing this, but it's done. There's follow-up work to be done, I'll file a separate issue for that. |
As part of #45538, we are incorporating knowledge of which variables are live (i.e., may be used later). We also distinguish "drop-live", which means that they may be dropped later.
However, in MIR, we sometimes generate drops that we can see statically will be a no-op. For example, consider this program:
The problem is that
p
is considered "drop-live" at the point wherev += 1
, because there is a DROP in the MIR, even though we know thatp
must have been moved (and hence will not be dropped) at that point.One way to account for this is to do a maybe initialized analysis. This is a forwards analysis that tells you, at any given point, whether a given value could possibly be initialized that this point. The idea then would be to change the code which invokes the
add_drop_live_constraint
function to take the "maybe initialized" state into account. In particular, if the local variable that is being dropped cannot be initialized (i.e., maybe initialized is false), then we can ignore the fact that it is drop live and just not invokeadd_drop_live_constraint
with its type.We are already computing a "maybe initialized" in the borrow checker (the variable
flow_inits
). However, this analysis works a bit differently than the NLL code. For example, it is computed at the level of fragments, which are paths likea.b.c
. This is done because it is possible thata
was initialized, but some subpart of it (e.g.,a.b.c
) was moved, while the rest remains intact.Honestly, all the data structures are a bit out of cache for me, but the high-level idea then is that, when we know that a variable
X
is drop-live, we want to iterate over all of the subpaths ofa
that may be initialized (which the existing data structures should be able to tell us) and then invoke the existingadd_drop_live_constraint
function on the types of those fragments.cc @arielb1 @pnkfelix -- any notes you care to leave on how to find the maybe initialized fragments given a
mir::Local
would be appreciated. Else I will dig into the data structures at some point.The text was updated successfully, but these errors were encountered: