diff --git a/src/destructors.md b/src/destructors.md index 6c7b2c9d..5b3f5468 100644 --- a/src/destructors.md +++ b/src/destructors.md @@ -26,14 +26,11 @@ this is totally fine. For instance, a custom implementation of `Box` might write `Drop` like this: ```rust -#![feature(alloc, heap_api, unique)] +#![feature(unique, allocator_api)] -extern crate alloc; - -use std::ptr::{drop_in_place, Unique}; +use std::heap::{Heap, Alloc, Layout}; use std::mem; - -use alloc::heap; +use std::ptr::{drop_in_place, Unique}; struct Box{ ptr: Unique } @@ -41,9 +38,7 @@ impl Drop for Box { fn drop(&mut self) { unsafe { drop_in_place(self.ptr.as_ptr()); - heap::deallocate(self.ptr.as_ptr() as *mut u8, - mem::size_of::(), - mem::align_of::()); + Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::()) } } } @@ -57,24 +52,19 @@ use-after-free the `ptr` because when drop exits, it becomes inaccessible. However this wouldn't work: ```rust -#![feature(alloc, heap_api, unique)] - -extern crate alloc; +#![feature(allocator_api, unique)] +use std::heap::{Heap, Alloc, Layout}; use std::ptr::{drop_in_place, Unique}; use std::mem; -use alloc::heap; - struct Box{ ptr: Unique } impl Drop for Box { fn drop(&mut self) { unsafe { drop_in_place(self.ptr.as_ptr()); - heap::deallocate(self.ptr.as_ptr() as *mut u8, - mem::size_of::(), - mem::align_of::()); + Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::()); } } } @@ -86,9 +76,7 @@ impl Drop for SuperBox { unsafe { // Hyper-optimized: deallocate the box's contents for it // without `drop`ing the contents - heap::deallocate(self.my_box.ptr.as_ptr() as *mut u8, - mem::size_of::(), - mem::align_of::()); + Heap.dealloc(self.my_box.ptr.as_ptr() as *mut u8, Layout::new::()); } } } @@ -135,24 +123,19 @@ The classic safe solution to overriding recursive drop and allowing moving out of Self during `drop` is to use an Option: ```rust -#![feature(alloc, heap_api, unique)] - -extern crate alloc; +#![feature(allocator_api, unique)] +use std::heap::{Alloc, Heap, Layout}; use std::ptr::{drop_in_place, Unique}; use std::mem; -use alloc::heap; - struct Box{ ptr: Unique } impl Drop for Box { fn drop(&mut self) { unsafe { drop_in_place(self.ptr.as_ptr()); - heap::deallocate(self.ptr.as_ptr() as *mut u8, - mem::size_of::(), - mem::align_of::()); + Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::()); } } } @@ -166,9 +149,7 @@ impl Drop for SuperBox { // without `drop`ing the contents. Need to set the `box` // field as `None` to prevent Rust from trying to Drop it. let my_box = self.my_box.take().unwrap(); - heap::deallocate(my_box.ptr.as_ptr() as *mut u8, - mem::size_of::(), - mem::align_of::()); + Heap.dealloc(my_box.ptr.as_ptr() as *mut u8, Layout::new::()); mem::forget(my_box); } } diff --git a/src/vec-final.md b/src/vec-final.md index cfea0d67..fd6c592c 100644 --- a/src/vec-final.md +++ b/src/vec-final.md @@ -2,16 +2,13 @@ ```rust #![feature(unique)] -#![feature(alloc, heap_api)] - -extern crate alloc; +#![feature(allocator_api)] use std::ptr::{Unique, self}; use std::mem; use std::ops::{Deref, DerefMut}; use std::marker::PhantomData; - -use alloc::heap; +use std::heap::{Alloc, Layout, Heap}; struct RawVec { ptr: Unique, @@ -35,22 +32,22 @@ impl RawVec { // 0, getting to here necessarily means the Vec is overfull. assert!(elem_size != 0, "capacity overflow"); - let align = mem::align_of::(); - let (new_cap, ptr) = if self.cap == 0 { - let ptr = heap::allocate(elem_size, align); + let ptr = Heap.alloc(Layout::array::(1).unwrap()); (1, ptr) } else { let new_cap = 2 * self.cap; - let ptr = heap::reallocate(self.ptr.as_ptr() as *mut _, - self.cap * elem_size, - new_cap * elem_size, - align); + let ptr = Heap.realloc(self.ptr.as_ptr() as *mut _, + Layout::array::(self.cap).unwrap(), + Layout::array::(new_cap).unwrap()); (new_cap, ptr) }; - // If allocate or reallocate fail, we'll get `null` back - if ptr.is_null() { oom() } + // If allocate or reallocate fail, oom + let ptr = match ptr { + Ok(ptr) => ptr, + Err(err) => Heap.oom(err), + }; self.ptr = Unique::new(ptr as *mut _); self.cap = new_cap; @@ -62,20 +59,14 @@ impl Drop for RawVec { fn drop(&mut self) { let elem_size = mem::size_of::(); if self.cap != 0 && elem_size != 0 { - let align = mem::align_of::(); - - let num_bytes = elem_size * self.cap; unsafe { - heap::deallocate(self.ptr.as_ptr() as *mut _, num_bytes, align); + Heap.dealloc(self.ptr.as_ptr() as *mut _, + Layout::array::(self.cap).unwrap()); } } } } - - - - pub struct Vec { buf: RawVec, len: usize,