-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[E0521] coroutine should own upvars and assigning internal references to moved captures does not leak the references #140132
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'm not sure if this part makes sense. This transformation is only sound if the closure implements only I'm not totally sure that this is worth fixing either, since it adds a somewhat nontrivial behavioral shift between whether a closure is I don't believe that this is a bug though, but instead an enhancement. Still not convinced that it's worth fixing, though. |
I agree with your opinion on There is surely only one body per coroutine that we generate and it takes ownership of its states throughout its lifecycle and a coroutine is not re-entrant like a What I worry about is that coroutines are not a real closure. They can capture like closures and the current syntax resembles a closure for some reason. Users may mistake them as false twins of Leaving discussion on the syntax and the false-twining consequence aside, I would like to introduce this enhancement is because it would also allow us to enable space-saving optimisation on the coroutine data layout. I believe this is a fair enhancement to bring onto coroutines. I hope that replacing the closure syntax with the |
Optional content for discussion Besides, I remark that we are already generating a separate body for an |
*FnOnce
closures should own upvars and there shall not be escaping borrows
I tried this code:
I expected to see this happen:
This should compile. The following is the current MIR of the coroutine at the analysis phase.
Instead, this happened:
This unfortunately does not compile.
This boils down to a borrow not living long enough due to the
StorageDead(_5)
statement inbb1
, at which_1
is still alive. However,_1.0
is a capture moved into the closure and is no longer accessible outside of this coroutine.Original issue description
I tried this code:
I expected to see this happen:
This should compile. The following is the current MIR of the closure at the analysis phase.
Note that the closure value
_1
has a correct type for aFnOnce
so that it is entirely owned by the closure body.Instead, this happened:
This unfortunately does not compile.
This boils down to a borrow not living long enough due to the
StorageDead(_2)
statement, at which_1
is still alive.A similar situation also applies to coroutines as implemented today. See this test suite
Meta
rustc --version --verbose
:The commit hash should be
49e5e4e3a5610c240a717cb99003a5d5d3356679
.Possible way forward
We could generate a separate body for
FnOnce
variant of closures, when requested, and apply a MIR transformation early to lift the upvars into their own locals. This is a known technique in #135527.Backtrace
The text was updated successfully, but these errors were encountered: