about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-04-11 16:57:40 +0200
committerGitHub <noreply@github.com>2024-04-11 16:57:40 +0200
commitee736603685a932817c7f21b385d6187ae548617 (patch)
tree8181fdfc9ef7f9b9a785c7654c66a46663f6bc58 /compiler/rustc_codegen_gcc/src
parent62cffeedcf353d8d5bd78cff9898c3def3e3cb84 (diff)
parent599d456a7532aa5de020b42fd1d9d936fa647573 (diff)
downloadrust-ee736603685a932817c7f21b385d6187ae548617.tar.gz
rust-ee736603685a932817c7f21b385d6187ae548617.zip
Rollup merge of #123660 - compiler-errors:coroutine-closure-env, r=oli-obk
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
Diffstat (limited to 'compiler/rustc_codegen_gcc/src')
0 files changed, 0 insertions, 0 deletions