Polonius and subset propagation
  • vec-push-ref, simplified
  • vec-push-ref, more complex
  • unnecessary-error
  • the roll of dead regions
  • issue-47680

vec-push-ref simplified


let mut vec = vec![];
let mut x = 22;
vec.push(&x);
x += 1; // ERROR
drop(vec);

let mut vec: Vec<&'a u32> = Vec::new();
let mut x = 22;

let tmp0: &'_ mut Vec<&'b u32> = &mut vec;
  // subset('a, 'b) 'a: 'b
  // subset('b, 'a) 'b: 'a
let tmp1: &'c u32 = &x; // Loan L0, 'c: {L0}
// ...
Vec::push(tmp0, tmp1); // (&mut Vec<T>, T), T = &'d u32
  // 'c: 'b
  // 'a: 'b // flows in from above
  // 'b: 'a
  // requires(L0, 'b)
  // requires(L0, 'c)
  // requires(L0, 'a) // transitive

x += 1; // error -- need L0 to be in scope
drop(vec); // live region: 'a, requires(L0, 'a)

vec-push-ref


let mut vec = vec![];
let mut x = 22;
let p = &x; // loan is created here
if foo {
  vec.push(p); // connection between type of p and the type of vec is created here
  x += 1; // ERROR
} else {
  x += 1; // OK
}
drop(vec);

unnecessary-error

link

fn unnecessary_error() {