-
Notifications
You must be signed in to change notification settings - Fork 13.3k
EndRegion and StorageDead are emitted in the wrong order #43481
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
I think I have a fix for this. (It was yet another place where I got the order wrong for emitting the |
Hmm no maybe I spoke too soon. The reason I'm hestiating is that my "fix" yields code like this:
We probably want the |
After looking into the code a bit, it seems like trying to change things so that we emit (hypothetical):
is likely to be more trouble than its worth. My thinking had been that it would be good to emit the above mir sequence in order to work toward a pair of flow graph properties like:
But I don't know that we really get a benefit out of such a strong pair of properties. From this description, it seems like @RalfJung wants to enforce property 2. But it seems reasonable to loosen property 1 to a weaker flow graph property, such as "1b. For all
(However, to play devil's advocate: Maybe one can make an analogous argument against trying to enforce even property 2? I.e., if one is already going to make the invariant be about operations and not the relative locations of |
I guess that would make sense; for my purposes, a "too late"
Yes, I think that's what I want. Really what I care about is that at the point of
I can only answer this in the context of my proposed "Types as Contracts", which is still so much in the air that it may or may not be good guideline. ;) But in this context, |
After discussion with @nikomatsakis , I think the path forward here is to just go ahead and make the change so that we enforce property 2 but do not attempt to enforce property 1. In other words, regions that have already ended will be allowed to occur in the types of lvals in a Just repeating for clarity: The property that we will strive to enforce, is this:
|
Sure. Borrowck also requires property (2), while nothing that I know of requires property (1). |
After further reflection, I realized this morning that in fact the two properties I listed are incompatible! You cannot have both. Therefore, it is a good thing that we decided to just enforce property 2. Why can't you have both? Because (aha) of cyclic references. E.g. examples like the following: use std::cell::Cell;
struct S<'a> {
r: Cell<Option<&'a S<'a>>>,
}
fn main() {
let x = S { r: Cell::new(None) };
x.r.set(Some(&x));
} Here we have an |
…or a scope. (The idea is that the StorageDead marks the point where the memory can be deallocated, and the EndRegion is marking where borrows of that memory can no longer legally exist.)
…sakis Fix end region emission order Fix #43481
This code
results in the following MIR (before region erasure):
So,
_4
is borrowed for this scope, but actually it is marked dead before the scope ends. That seems wrong to me, shouldn't_4
have to be live at least until the region ends?Cc @pnkfelix @nikomatsakis
The text was updated successfully, but these errors were encountered: