diff --git a/src/destructors.md b/src/destructors.md index 2f9e7aa..daadd1f 100644 --- a/src/destructors.md +++ b/src/destructors.md @@ -28,9 +28,9 @@ For instance, a custom implementation of `Box` might write `Drop` like this: ```rust #![feature(ptr_internals, allocator_api, unique)] -use std::alloc::{Global, GlobalAlloc, Layout}; +use std::alloc::{Alloc, Global, GlobalAlloc, Layout}; use std::mem; -use std::ptr::{drop_in_place, Unique}; +use std::ptr::{drop_in_place, NonNull, Unique}; struct Box{ ptr: Unique } @@ -38,7 +38,8 @@ impl Drop for Box { fn drop(&mut self) { unsafe { drop_in_place(self.ptr.as_ptr()); - Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::()) + let c: NonNull = self.ptr.into(); + Global.dealloc(c.cast(), Layout::new::()) } } } @@ -54,8 +55,8 @@ However this wouldn't work: ```rust #![feature(allocator_api, ptr_internals, unique)] -use std::alloc::{Global, GlobalAlloc, Layout}; -use std::ptr::{drop_in_place, Unique}; +use std::alloc::{Alloc, Global, GlobalAlloc, Layout}; +use std::ptr::{drop_in_place, Unique, NonNull}; use std::mem; struct Box{ ptr: Unique } @@ -64,7 +65,8 @@ impl Drop for Box { fn drop(&mut self) { unsafe { drop_in_place(self.ptr.as_ptr()); - Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::()); + let c: NonNull = self.ptr.into(); + Global.dealloc(c.cast(), Layout::new::()); } } } @@ -76,7 +78,8 @@ impl Drop for SuperBox { unsafe { // Hyper-optimized: deallocate the box's contents for it // without `drop`ing the contents - Global.dealloc(self.my_box.ptr.as_ptr() as *mut _, Layout::new::()); + let c: NonNull = self.my_box.ptr.into(); + Global.dealloc(c.cast::(), Layout::new::()); } } } @@ -125,8 +128,8 @@ of Self during `drop` is to use an Option: ```rust #![feature(allocator_api, ptr_internals, unique)] -use std::alloc::{GlobalAlloc, Global, Layout}; -use std::ptr::{drop_in_place, Unique}; +use std::alloc::{Alloc, GlobalAlloc, Global, Layout}; +use std::ptr::{drop_in_place, Unique, NonNull}; use std::mem; struct Box{ ptr: Unique } @@ -135,7 +138,8 @@ impl Drop for Box { fn drop(&mut self) { unsafe { drop_in_place(self.ptr.as_ptr()); - Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::()); + let c: NonNull = self.ptr.into(); + Global.dealloc(c.cast(), Layout::new::()); } } } @@ -149,7 +153,8 @@ 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(); - Global.dealloc(my_box.ptr.as_ptr() as *mut _, Layout::new::()); + let c: NonNull = my_box.ptr.into(); + Global.dealloc(c.cast(), Layout::new::()); mem::forget(my_box); } } diff --git a/src/vec-final.md b/src/vec-final.md index 199528a..b9fd942 100644 --- a/src/vec-final.md +++ b/src/vec-final.md @@ -5,11 +5,11 @@ #![feature(allocator_api)] #![feature(unique)] -use std::ptr::{Unique, self}; +use std::ptr::{Unique, NonNull, self}; use std::mem; use std::ops::{Deref, DerefMut}; use std::marker::PhantomData; -use std::alloc::{GlobalAlloc, Layout, Global, oom}; +use std::alloc::{Alloc, GlobalAlloc, Layout, Global, oom}; struct RawVec { ptr: Unique, @@ -38,18 +38,23 @@ impl RawVec { (1, ptr) } else { let new_cap = 2 * self.cap; - let ptr = Global.realloc(self.ptr.as_ptr() as *mut _, + let c: NonNull = self.ptr.into(); + let ptr = Global.realloc(c.cast(), Layout::array::(self.cap).unwrap(), Layout::array::(new_cap).unwrap().size()); (new_cap, ptr) }; // If allocate or reallocate fail, oom - if ptr.is_null() { - oom() + if ptr.is_err() { + oom(Layout::from_size_align_unchecked( + new_cap * elem_size, + mem::align_of::(), + )) } + let ptr = ptr.unwrap(); - self.ptr = Unique::new_unchecked(ptr as *mut _); + self.ptr = Unique::new_unchecked(ptr.as_ptr() as *mut _); self.cap = new_cap; } } @@ -60,7 +65,8 @@ impl Drop for RawVec { let elem_size = mem::size_of::(); if self.cap != 0 && elem_size != 0 { unsafe { - Global.dealloc(self.ptr.as_ptr() as *mut _, + let c: NonNull = self.ptr.into(); + Global.dealloc(c.cast(), Layout::array::(self.cap).unwrap()); } }