Closed
Description
STR
struct Bomb;
struct Observer<'a>(&'a mut (String, Bomb));
impl Drop for Bomb {
fn drop(&mut self) {
panic!("panicking destructors ftw!");
}
}
impl<'a> Drop for Observer<'a> {
fn drop(&mut self) {
let _spray = "0wned".to_owned();
println!("{}", &self.0 .0);
}
}
fn foo(b: &mut Observer) {
*b.0 = ("~".to_owned(), Bomb);
}
fn main() {
let mut bomb = ("clear".to_owned(), Bomb);
let mut observer = Observer(&mut bomb);
foo(&mut observer);
}
Results
The assignment to *b.0
within foo
calls the drop-glue for the value inside. The new tuple ("~", Bomb)
is created, and then the drop glue for the old value of b
is executed. It first frees the original string, and then attempts to calls Bomb
's destructor. As the latter destructor panics, the function unwinds without storing a value in the place of the missing String
, leaving a &mut
reference that points to an invalid value, which can later be observed by a destructor or recover
.
Fixes
The new value for the destination is available the whole time - the panic handler can just write it in.