Merge pull request #73 from Mark-Simulacrum/fix

Fix nomicon for allocator changes
pull/74/head
Steve Klabnik 7 years ago committed by GitHub
commit 13e3745ca3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -28,9 +28,9 @@ For instance, a custom implementation of `Box` might write `Drop` like this:
```rust ```rust
#![feature(ptr_internals, allocator_api, unique)] #![feature(ptr_internals, allocator_api, unique)]
use std::alloc::{Global, GlobalAlloc, Layout}; use std::alloc::{Alloc, Global, GlobalAlloc, Layout};
use std::mem; use std::mem;
use std::ptr::{drop_in_place, Unique}; use std::ptr::{drop_in_place, NonNull, Unique};
struct Box<T>{ ptr: Unique<T> } struct Box<T>{ ptr: Unique<T> }
@ -38,7 +38,8 @@ impl<T> Drop for Box<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
drop_in_place(self.ptr.as_ptr()); drop_in_place(self.ptr.as_ptr());
Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::<T>()) let c: NonNull<T> = self.ptr.into();
Global.dealloc(c.cast(), Layout::new::<T>())
} }
} }
} }
@ -54,8 +55,8 @@ However this wouldn't work:
```rust ```rust
#![feature(allocator_api, ptr_internals, unique)] #![feature(allocator_api, ptr_internals, unique)]
use std::alloc::{Global, GlobalAlloc, Layout}; use std::alloc::{Alloc, Global, GlobalAlloc, Layout};
use std::ptr::{drop_in_place, Unique}; use std::ptr::{drop_in_place, Unique, NonNull};
use std::mem; use std::mem;
struct Box<T>{ ptr: Unique<T> } struct Box<T>{ ptr: Unique<T> }
@ -64,7 +65,8 @@ impl<T> Drop for Box<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
drop_in_place(self.ptr.as_ptr()); drop_in_place(self.ptr.as_ptr());
Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::<T>()); let c: NonNull<T> = self.ptr.into();
Global.dealloc(c.cast(), Layout::new::<T>());
} }
} }
} }
@ -76,7 +78,8 @@ impl<T> Drop for SuperBox<T> {
unsafe { unsafe {
// Hyper-optimized: deallocate the box's contents for it // Hyper-optimized: deallocate the box's contents for it
// without `drop`ing the contents // without `drop`ing the contents
Global.dealloc(self.my_box.ptr.as_ptr() as *mut _, Layout::new::<T>()); let c: NonNull<T> = self.my_box.ptr.into();
Global.dealloc(c.cast::<u8>(), Layout::new::<T>());
} }
} }
} }
@ -125,8 +128,8 @@ of Self during `drop` is to use an Option:
```rust ```rust
#![feature(allocator_api, ptr_internals, unique)] #![feature(allocator_api, ptr_internals, unique)]
use std::alloc::{GlobalAlloc, Global, Layout}; use std::alloc::{Alloc, GlobalAlloc, Global, Layout};
use std::ptr::{drop_in_place, Unique}; use std::ptr::{drop_in_place, Unique, NonNull};
use std::mem; use std::mem;
struct Box<T>{ ptr: Unique<T> } struct Box<T>{ ptr: Unique<T> }
@ -135,7 +138,8 @@ impl<T> Drop for Box<T> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
drop_in_place(self.ptr.as_ptr()); drop_in_place(self.ptr.as_ptr());
Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::<T>()); let c: NonNull<T> = self.ptr.into();
Global.dealloc(c.cast(), Layout::new::<T>());
} }
} }
} }
@ -149,7 +153,8 @@ impl<T> Drop for SuperBox<T> {
// without `drop`ing the contents. Need to set the `box` // without `drop`ing the contents. Need to set the `box`
// field as `None` to prevent Rust from trying to Drop it. // field as `None` to prevent Rust from trying to Drop it.
let my_box = self.my_box.take().unwrap(); let my_box = self.my_box.take().unwrap();
Global.dealloc(my_box.ptr.as_ptr() as *mut _, Layout::new::<T>()); let c: NonNull<T> = my_box.ptr.into();
Global.dealloc(c.cast(), Layout::new::<T>());
mem::forget(my_box); mem::forget(my_box);
} }
} }

@ -5,11 +5,11 @@
#![feature(allocator_api)] #![feature(allocator_api)]
#![feature(unique)] #![feature(unique)]
use std::ptr::{Unique, self}; use std::ptr::{Unique, NonNull, self};
use std::mem; use std::mem;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::alloc::{GlobalAlloc, Layout, Global, oom}; use std::alloc::{Alloc, GlobalAlloc, Layout, Global, oom};
struct RawVec<T> { struct RawVec<T> {
ptr: Unique<T>, ptr: Unique<T>,
@ -38,18 +38,23 @@ impl<T> RawVec<T> {
(1, ptr) (1, ptr)
} else { } else {
let new_cap = 2 * self.cap; let new_cap = 2 * self.cap;
let ptr = Global.realloc(self.ptr.as_ptr() as *mut _, let c: NonNull<T> = self.ptr.into();
let ptr = Global.realloc(c.cast(),
Layout::array::<T>(self.cap).unwrap(), Layout::array::<T>(self.cap).unwrap(),
Layout::array::<T>(new_cap).unwrap().size()); Layout::array::<T>(new_cap).unwrap().size());
(new_cap, ptr) (new_cap, ptr)
}; };
// If allocate or reallocate fail, oom // If allocate or reallocate fail, oom
if ptr.is_null() { if ptr.is_err() {
oom() oom(Layout::from_size_align_unchecked(
new_cap * elem_size,
mem::align_of::<T>(),
))
} }
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; self.cap = new_cap;
} }
} }
@ -60,7 +65,8 @@ impl<T> Drop for RawVec<T> {
let elem_size = mem::size_of::<T>(); let elem_size = mem::size_of::<T>();
if self.cap != 0 && elem_size != 0 { if self.cap != 0 && elem_size != 0 {
unsafe { unsafe {
Global.dealloc(self.ptr.as_ptr() as *mut _, let c: NonNull<T> = self.ptr.into();
Global.dealloc(c.cast(),
Layout::array::<T>(self.cap).unwrap()); Layout::array::<T>(self.cap).unwrap());
} }
} }

Loading…
Cancel
Save