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 Drop Locations

This step makes explicit where drops may happen, using the ensure_dropped! macro.

We add ensure_dropped! statements in two locations: at end of scopes and before variable assignments.

#![allow(unused)]
fn main() {
scope_end!($local);

// becomes:
ensure_dropped!($local);
scope_end!($local);
}
#![allow(unused)]
fn main() {
$place = $expr;

// becomes:
ensure_dropped!($place);
$place = $expr;
}

One tricky case is assignment through a mutable reference:

#![allow(unused)]
fn main() {
let a: &mut String = ...;
*a = String::new(); // this drops the previous string

// becomes:
ensure_dropped!(*a); // this drops the previous string
*a = String::new(); // borrowck knows there's no previous string to drop
}

This is not allowed in today's Rust, but is legal for us thanks to the Moving Out Of &mut feature.

After this step, all assignments are to statically uninitialized places (hence won't cause implicit drops), and scope_end never needs to drop anything.