Improve upvar analysis for deref of child capture by compiler-errors · Pull Request #138517 · rust-lang/rust (original) (raw)
Two fixes to the heuristic I implemented in #123660. As I noted in the code:
Luckily, if this function 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.
This indeed fixes unnecessary borrowck errors.
r? oli-obk
The heuristic is only valid if we deref a &T
, not a &mut T
or Box<T>
, so make sure to check the type. This fixes:
struct Foo { precise: i32 }
fn mut_ref_inside_mut(f: &mut Foo) { let x: impl AsyncFn() = async move || { let y = &f.precise; }; }
Since the capture from f
to &f.precise
needs to be treated as a lending borrow from the parent coroutine-closure to the child coroutine.
The heuristic is also valid if any deref projection in the child capture's projections is a &T
, but we were only looking at the last one. This ensures that this function is considered not to be lending:
struct Foo { precise: i32 }
fn ref_inside_mut(f: &mut &Foo) { let x: impl Fn() -> _ = async move || { let y = &f.precise; }; }
(Specifically, checking that impl Fn() -> _
is satisfied is exercising that the coroutine is not considered to be lending.)