@ -26,13 +26,16 @@ this is totally fine.
For instance, a custom implementation of `Box` might write `Drop` like this:
For instance, a custom implementation of `Box` might write `Drop` like this:
```rust
```rust
#![feature(heap_api, core_intrinsics, unique)]
#![feature(alloc, heap_api, core_intrinsics, unique)]
extern crate alloc;
use std::rt::heap;
use std::ptr::Unique;
use std::ptr::Unique;
use std::intrinsics::drop_in_place;
use std::intrinsics::drop_in_place;
use std::mem;
use std::mem;
use alloc::heap;
struct Box< T > { ptr: Unique< T > }
struct Box< T > { ptr: Unique< T > }
impl< T > Drop for Box< T > {
impl< T > Drop for Box< T > {
@ -45,6 +48,7 @@ impl<T> Drop for Box<T> {
}
}
}
}
}
}
# fn main() {}
```
```
and this works fine because when Rust goes to drop the `ptr` field it just sees
and this works fine because when Rust goes to drop the `ptr` field it just sees
@ -54,13 +58,16 @@ use-after-free the `ptr` because when drop exits, it becomes inacessible.
However this wouldn't work:
However this wouldn't work:
```rust
```rust
#![feature(heap_api, core_intrinsics, unique)]
#![feature(alloc, heap_api, core_intrinsics, unique)]
extern crate alloc;
use std::rt::heap;
use std::ptr::Unique;
use std::ptr::Unique;
use std::intrinsics::drop_in_place;
use std::intrinsics::drop_in_place;
use std::mem;
use std::mem;
use alloc::heap;
struct Box< T > { ptr: Unique< T > }
struct Box< T > { ptr: Unique< T > }
impl< T > Drop for Box< T > {
impl< T > Drop for Box< T > {
@ -87,6 +94,7 @@ impl<T> Drop for SuperBox<T> {
}
}
}
}
}
}
# fn main() {}
```
```
After we deallocate the `box` 's ptr in SuperBox's destructor, Rust will
After we deallocate the `box` 's ptr in SuperBox's destructor, Rust will
@ -129,13 +137,16 @@ The classic safe solution to overriding recursive drop and allowing moving out
of Self during `drop` is to use an Option:
of Self during `drop` is to use an Option:
```rust
```rust
#![feature(heap_api, core_intrinsics, unique)]
#![feature(alloc, heap_api, core_intrinsics, unique)]
extern crate alloc;
use std::rt::heap;
use std::ptr::Unique;
use std::ptr::Unique;
use std::intrinsics::drop_in_place;
use std::intrinsics::drop_in_place;
use std::mem;
use std::mem;
use alloc::heap;
struct Box< T > { ptr: Unique< T > }
struct Box< T > { ptr: Unique< T > }
impl< T > Drop for Box< T > {
impl< T > Drop for Box< T > {
@ -165,6 +176,7 @@ impl<T> Drop for SuperBox<T> {
}
}
}
}
}
}
# fn main() {}
```
```
However this has fairly odd semantics: you're saying that a field that *should*
However this has fairly odd semantics: you're saying that a field that *should*