mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
ee73660368
Make the computation of `coroutine_captures_by_ref_ty` more sophisticated Currently, we treat all the by-(mut/)ref borrows of a coroutine-closure as having a "closure env" borrowed lifetime. When we have the given code: ```rust let x: &'a i32 = ...; let c = async || { let _x = *x; }; ``` Then when we call: ```rust c() // which, because `AsyncFn` takes a `&self`, we insert an autoref: (&c /* &'env {coroutine-closure} */)() ``` We will return a future whose captures contain `&'env i32` instead of `&'a i32`, which is way more restrictive than necessary. We should be able to drop `c` while the future is alive since it's not actually borrowing any data *originating from within* the closure's captures, but since the capture has that `'env` lifetime, this is not possible. This wouldn't be true, for example, if the closure captured `i32` instead of `&'a i32`, because the `'env` lifetime is actually *necessary* since the data (`i32`) is owned by the closure. This PR identifies two criteria where we *need* to take the borrow with the closure env lifetime: 1. If the closure borrows data from inside the closure's captures. This is not true if the parent capture is by-ref, OR if the parent capture is by-move and the child capture begins with a deref projection. This is the example described above. 2. If we're dealing with mutable references, since we cannot reborrow `&'env mut &'a mut i32` into `&'a mut i32`, *only* `&'env mut i32`. See the documentation on `should_reborrow_from_env_of_parent_coroutine_closure` for more info. **important:** As disclaimer states on that function, luckily, if this heuristic is not correct, then the program is not unsound, since we still borrowck and validate the choices made from this function -- the only side-effect is that the user may receive unnecessary borrowck errors. Fixes #123241 |
||
---|---|---|
.. | ||
src | ||
Cargo.toml | ||
messages.ftl | ||
README.md |
For more information about how rustc works, see the rustc dev guide.