E4005

E4005 — A value that points into this function's stack frame would outlive the function: a reference to a local, or a closure that uses one, returned (on its own or inside a struct), stored through a reference, or passed to a call that could store it there. What it points at is gone once the function returns. The same holds inside a function for a block: a variable declared outside a block cannot be given a value that points at a variable declared inside it. Nor can a variable keep a reference into a value with no name, such as make_vec() in let r = &make_vec();, when that value is dropped at the end of its statement. A closure cannot return a reference to its own parameter, or to the copy it keeps of a variable it uses (|| &x): each call has its own frame.

What the compiler reports

E4005

The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.

A program that triggers it

// Return-escape analysis (#243, case bc4): returning `&x` for a function-local `x`
// leaves a dangling reference once the frame unwinds. Must be rejected.
fn dangle() -> &i32 {
  let x = 5;
  return &x;
}
fn main() -> i32 {
  return 0;
}

From tests/middle_end/fail/borrow_return_local_ref.vx, which asserts this diagnostic on every commit.

Related