Skip to content
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

Kill moved locals in borrowed locals analysis #110420

Closed
wants to merge 2 commits into from

Conversation

b-naber
Copy link
Contributor

@b-naber b-naber commented Apr 16, 2023

We currently solely rely on StorageDead statements when killing locals in the borrowed locals analysis. Killing locals when they're moved should be fine since the borrow checker guarantees that there aren't any used borrows after the move. Currently this change only kills locals corresponding to Places that don't have any projections, though we could in principle also track moves of projections here. Not sure whether this is worth it given that we will be move to drop-tracking and mir-drop-tracking at some point. Still, the current change seems like an improvement to me until then.

Fixes #96084
Fixes #94067 (I think? I believe the example by @eholk was missing a Send impl on Agent)

r? @tmandry maybe?

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 16, 2023
@rustbot
Copy link
Collaborator

rustbot commented Apr 16, 2023

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

@JakobDegen
Copy link
Contributor

Unfortunately, we can't do this. Putting aside for a minute that post-drop elab Mir is not expected to pass borrowck (and doesn't), this is also wrong in other cases:

async {
    let x = String::new();
    let p = &x as *const _;
    let _y = x;
    something.await;
    dbg!(*p);
}

There's a UCG issue tracking whether such code is UB or not, but we should not be assuming otherwise in the compiler

@b-naber
Copy link
Contributor Author

b-naber commented Apr 17, 2023

Thanks for pointing this out.

Putting aside for a minute that post-drop elab Mir is not expected to pass borrowck (and doesn't)

Can you maybe elaborate on this, please (sorry not really that familiar with mir optimizations)?

this is also wrong in other cases:

async {
    let x = String::new();
    let p = &x as *const _;
    let _y = x;
    something.await;
    dbg!(*p);
}

There's a UCG issue tracking whether such code is UB or not, but we should not be assuming otherwise in the compiler

Do you happen to have a link for that issue? Is this the one you're referring to (this doesn't seem to touch on whether the provided example is UB or not, but I couldn't find any other issue that seemed more relevant).

I only skimmed your proposal, but it seems to me that something like a generator table would solve the 'future sizes' problem?!

Alternatively (though I haven't had time to properly think this through): What if we were to track "live" borrows and raw pointers (and keep a borrow/raw ptr -> local map) in the dataflow analysis for borrowed locals? That should also provide sufficient information to let us infer whether to keep a local across a yield point I think... Is there a flaw in that thinking?

@JakobDegen
Copy link
Contributor

rust-lang/unsafe-code-guidelines#188 is the issue.

What if we were to track "live" borrows and raw pointers (and keep a borrow/raw ptr -> local map) in the dataflow analysis for borrowed locals? That should also provide sufficient information to let us infer whether to keep a local across a yield point I think... Is there a flaw in that thinking?

There's nothing inherently flawed about this - doing more careful analysis lets us do more complicated optimizations. The difficulty is only in doing that analysis correctly. I'd invite you to share on Zulip if you have some concrete ideas for what you want to try

@b-naber
Copy link
Contributor Author

b-naber commented Apr 26, 2023

Thanks for the answer, I'll ping you on zulip.

I'll go ahead and close this PR.

@b-naber b-naber closed this Apr 26, 2023
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 4, 2023
Stop considering moved-out locals when computing auto traits for generators

Addresses rust-lang#94067 (but does not fix it since drop-tracking-mir is unstable)

This PR, unlike rust-lang#110420 or rust-lang#112050, does not attempt to reduce the number of live locals across suspension points. It however ignores moved-out locals for trait purposes. So this PR solves the non-send issue, but not the size issue.

Suggested by `@RalfJung` in [rust-lang/unsafe-code-guidelines#188](rust-lang/unsafe-code-guidelines#188 (comment))

cc `@b-naber` who's working on this from a different perspective.

r? `@cjgillot`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
4 participants