Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Explicit Unwind Cleanup

In this step we make explicit the cleanup that happens on unwinding, using the Cleanup On Unwinding feature.

We surround every function call and every use of ensure_dropped with an on_unwind block. In the cleanup part of this block, we add ensure_dropped!($local); scope_end!($local); statements for each in-scope local, in reverse order of declaration.

#![allow(unused)]
fn main() {
let n = 42;
let x = String::new();

// becomes, before this stage:
let n;
n = 42;
let x;
x = String::new();
ensure_dropped!(x);
scope_end!(x);
ensure_dropped!(n);
scope_end!(n);

// becomes, after this stage:
let n;
n = 42;
let x;
x = on_unwind String::new() {
    ensure_dropped!(x);
    scope_end!(x);
    ensure_dropped!(n);
    scope_end!(n);
};
on_unwind ensure_dropped!(x) {
    ensure_dropped!(x);
    scope_end!(x);
    ensure_dropped!(n);
    scope_end!(n);
};
scope_end!(x);
on_unwind ensure_dropped!(n) {
    ensure_dropped!(n);
    scope_end!(n);
};
scope_end!(n);
}

After this step, unwinding no longer causes any code to run implicitly; it has all been made explicit.