mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-28 20:16:58 +03:00
e9f6e01b3a
Improve upvar analysis for deref of child capture 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: ```rust 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: ```rust 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.)