Coroutine tracing of borrows is quite conservative

ebc807f
Opened by Niko Matsakis at 2023-10-21 20:05:42

This example really should work, but does not:

fn yield_during_range_iter() {
    // Should be OK.
    let mut b = || {
        let v = vec![1,2,3];
        for i in 0..v.len() {
            yield v[i];
        }
    };
    b.resume();
}

fn main() { }

I get:

error[E0624]: borrow may still be in use when generator yields
  --> /home/nmatsakis/versioned/rust-1/src/test/ui/generator/yield-while-iterating.rs:75:21
   |
75 |         for i in 0..v.len() {
   |                     ^
76 |             yield v[i];
   |             ---------- possible yield occurs here

error[E0624]: borrow may still be in use when generator yields
  --> /home/nmatsakis/versioned/rust-1/src/test/ui/generator/yield-while-iterating.rs:76:19
   |
76 |             yield v[i];
   |             ------^--- possible yield occurs here

I think the problem is that the current code for deciding which temporaries are in scope is quite overly conservative. (On a related note, we also have to unconditionally throw booleans into the mix because of drop flags.)

cc @Zoxc @alexcrichton

  1. @rustbot label +F-generators +A-generators

    LucasFA at 2023-05-15 00:39:42