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 asmake_vec()inlet 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
Ownership and borrowingThe chapter covering the rule this code enforces.
All diagnosticsEvery code the compiler can emit, grouped by stage.
E4004Cannot borrow (already mutably borrowed)
E4006An assignment through a shared reference:
*r = v, r.f = v or r[i] = v where r is a &T. A shared reference only reads; writing needs a &mut T.