-
Notifications
You must be signed in to change notification settings - Fork 74
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
incorporate liveness computation into this crate #104
Comments
Part 1: Computing which variables are live where in polonius.Step listing
Datafrog rulesFirst, a variable is live on entry to P if it is used there:
Next, a variable is live on entry to P if it is used in a successor Q and P does not reassign it:
At this point, we should be able to write some unit tests where we supply some base facts and a control-flow graph and then test |
Once this is done, the next step will be to extend rustc to produce the |
Part 2Extending rustc to produce the First off, you will want to modify rustc to work with a local copy of polonius, so that you can edit the two in tandem. I think @AlbinS you've already figured this part out so I'll just assume you have done so. We're going to want to instantiate the polonius output with the "variable id" mapped to the The existing NLL liveness computation code for rustc lives in liveness/mod.rs -- note that there are other files named liveness.rs that are totally independent. =) We won't really be re-using much of it, but it has some bits and pieces that are useful. In fact, the For our purposes, a One twist of the liveness code is that it can sometimes only compute liveness for a subset of the variables -- those that might possible be interesting. This is what is going on in this part of the code. We presently disable that optimization when in polonius-fact mode, however, and I imagine we should just continue doing that for now. So basically what we would want to do I think is to generate the var-defined and var-used facts by doing the same sort of walk as the map does. But instead of inserting those facts into the The liveness code has acecss to the So I think what I would do is to extend the |
So I think that the next step is to compute "region-live-at" based on the liveness information. The basic idea here is this:
The rules for drop live regions values are the same, except that we don't use the full set of regions R in that case. To model this in polonius, then, I think we need another few relations. There are a few ways we could do it. Here is one way:
Then we would want to make some rules like:
The work then would be to:
|
I think the way I would structure the previous steps is as follows:
At this point, the results will no longer be correct for drops, though, so we have to start producing |
The
|
I see; and that should be straightforward because it's the same process as for uses and definitions, just another arm of the match statement in rustc. I'll start there! |
And this is an input field like let x: &'region = something_that_gives_a_reference();
// ... code
drop(x); // this <=> var_drops_region(x, 'region) |
This is now implemented! |
Regarding The idea is: when this variable However, I am also remembering now that the actual logic implemented by the NLL checker is a bit more complex than we originally envisioned in the RFC. I'll have to review what precisely we are doing there, but iirc we (at minimum) take into account initialization of variables and things. That said, I suspect we can ignore this for the first iteration, and come back to it after we get some other pieces (notably, the initialization analysis!) in place. |
So it seems like the next step, @AlbinS, is that we need to generate the The current code that generates those in rustc is here:
Both of these make use of the You can see that we also emit the One difference is that, in the existing code, these functions also take a set of points So I think what you want to do in your branch is to extend the "popular var liveness function" so that it iterates over the variables declared in for (local, local_decl) in mir.local_decls.iter_enumerated() {
...
} then, in the loop, get the type of each local from the for ... {
add_regions(local, local_decl.ty, &mut all_facts.var_uses_regions);
add_regions(local, local_decl.ty, &mut all_facts.var_drops_regions); // FIXME(polonius#104) overapproximation
} and then we would have to define fn add_regions(tcx: TyCtxt<'_, 'tcx, '_>, local: Local, ty: Ty<'tcx>, output_relation: &mut Vec<(...)>) {
tcx.for_each_free_region(..., |r| output_relation.push((local, r));
} Something like that, anyway. |
The following is left to do (for me):
Bonus tasks:
|
Fact generation for liveness calculations in Polonius This PR tracks ongoing work to extend `rustc` with support for generating variable use, definition, and later also drop output for the Polonius solver, the whole of which is being tracked in [Polonius Issue #104](rust-lang/polonius#104).
This has now been merged. Closing!! |
This is part of a general move to incorporate more of the borrow check computations into polonius itself. The overall goal here is that rustc will supply polonius with facts that say "this variable is defined here, this variable is used there" as well as which regions appear within the variable's type, and polonius will compute the
region_live_at
relation based on that (right now, theregion_live_at
relation is an input to polonius).We covered the overall plan in this YouTube video.
The text was updated successfully, but these errors were encountered: