Skip to content

Commit 13e3745

Browse files
authored
Merge pull request #73 from Mark-Simulacrum/fix
Fix nomicon for allocator changes
2 parents c5d5e58 + a9b5885 commit 13e3745

File tree

2 files changed

+29
-18
lines changed

2 files changed

+29
-18
lines changed

src/destructors.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,18 @@ For instance, a custom implementation of `Box` might write `Drop` like this:
2828
```rust
2929
#![feature(ptr_internals, allocator_api, unique)]
3030

31-
use std::alloc::{Global, GlobalAlloc, Layout};
31+
use std::alloc::{Alloc, Global, GlobalAlloc, Layout};
3232
use std::mem;
33-
use std::ptr::{drop_in_place, Unique};
33+
use std::ptr::{drop_in_place, NonNull, Unique};
3434

3535
struct Box<T>{ ptr: Unique<T> }
3636

3737
impl<T> Drop for Box<T> {
3838
fn drop(&mut self) {
3939
unsafe {
4040
drop_in_place(self.ptr.as_ptr());
41-
Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::<T>())
41+
let c: NonNull<T> = self.ptr.into();
42+
Global.dealloc(c.cast(), Layout::new::<T>())
4243
}
4344
}
4445
}
@@ -54,8 +55,8 @@ However this wouldn't work:
5455
```rust
5556
#![feature(allocator_api, ptr_internals, unique)]
5657

57-
use std::alloc::{Global, GlobalAlloc, Layout};
58-
use std::ptr::{drop_in_place, Unique};
58+
use std::alloc::{Alloc, Global, GlobalAlloc, Layout};
59+
use std::ptr::{drop_in_place, Unique, NonNull};
5960
use std::mem;
6061

6162
struct Box<T>{ ptr: Unique<T> }
@@ -64,7 +65,8 @@ impl<T> Drop for Box<T> {
6465
fn drop(&mut self) {
6566
unsafe {
6667
drop_in_place(self.ptr.as_ptr());
67-
Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::<T>());
68+
let c: NonNull<T> = self.ptr.into();
69+
Global.dealloc(c.cast(), Layout::new::<T>());
6870
}
6971
}
7072
}
@@ -76,7 +78,8 @@ impl<T> Drop for SuperBox<T> {
7678
unsafe {
7779
// Hyper-optimized: deallocate the box's contents for it
7880
// without `drop`ing the contents
79-
Global.dealloc(self.my_box.ptr.as_ptr() as *mut _, Layout::new::<T>());
81+
let c: NonNull<T> = self.my_box.ptr.into();
82+
Global.dealloc(c.cast::<u8>(), Layout::new::<T>());
8083
}
8184
}
8285
}
@@ -125,8 +128,8 @@ of Self during `drop` is to use an Option:
125128
```rust
126129
#![feature(allocator_api, ptr_internals, unique)]
127130

128-
use std::alloc::{GlobalAlloc, Global, Layout};
129-
use std::ptr::{drop_in_place, Unique};
131+
use std::alloc::{Alloc, GlobalAlloc, Global, Layout};
132+
use std::ptr::{drop_in_place, Unique, NonNull};
130133
use std::mem;
131134

132135
struct Box<T>{ ptr: Unique<T> }
@@ -135,7 +138,8 @@ impl<T> Drop for Box<T> {
135138
fn drop(&mut self) {
136139
unsafe {
137140
drop_in_place(self.ptr.as_ptr());
138-
Global.dealloc(self.ptr.as_ptr() as *mut _, Layout::new::<T>());
141+
let c: NonNull<T> = self.ptr.into();
142+
Global.dealloc(c.cast(), Layout::new::<T>());
139143
}
140144
}
141145
}
@@ -149,7 +153,8 @@ impl<T> Drop for SuperBox<T> {
149153
// without `drop`ing the contents. Need to set the `box`
150154
// field as `None` to prevent Rust from trying to Drop it.
151155
let my_box = self.my_box.take().unwrap();
152-
Global.dealloc(my_box.ptr.as_ptr() as *mut _, Layout::new::<T>());
156+
let c: NonNull<T> = my_box.ptr.into();
157+
Global.dealloc(c.cast(), Layout::new::<T>());
153158
mem::forget(my_box);
154159
}
155160
}

src/vec-final.md

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
#![feature(allocator_api)]
66
#![feature(unique)]
77

8-
use std::ptr::{Unique, self};
8+
use std::ptr::{Unique, NonNull, self};
99
use std::mem;
1010
use std::ops::{Deref, DerefMut};
1111
use std::marker::PhantomData;
12-
use std::alloc::{GlobalAlloc, Layout, Global, oom};
12+
use std::alloc::{Alloc, GlobalAlloc, Layout, Global, oom};
1313

1414
struct RawVec<T> {
1515
ptr: Unique<T>,
@@ -38,18 +38,23 @@ impl<T> RawVec<T> {
3838
(1, ptr)
3939
} else {
4040
let new_cap = 2 * self.cap;
41-
let ptr = Global.realloc(self.ptr.as_ptr() as *mut _,
41+
let c: NonNull<T> = self.ptr.into();
42+
let ptr = Global.realloc(c.cast(),
4243
Layout::array::<T>(self.cap).unwrap(),
4344
Layout::array::<T>(new_cap).unwrap().size());
4445
(new_cap, ptr)
4546
};
4647

4748
// If allocate or reallocate fail, oom
48-
if ptr.is_null() {
49-
oom()
49+
if ptr.is_err() {
50+
oom(Layout::from_size_align_unchecked(
51+
new_cap * elem_size,
52+
mem::align_of::<T>(),
53+
))
5054
}
55+
let ptr = ptr.unwrap();
5156

52-
self.ptr = Unique::new_unchecked(ptr as *mut _);
57+
self.ptr = Unique::new_unchecked(ptr.as_ptr() as *mut _);
5358
self.cap = new_cap;
5459
}
5560
}
@@ -60,7 +65,8 @@ impl<T> Drop for RawVec<T> {
6065
let elem_size = mem::size_of::<T>();
6166
if self.cap != 0 && elem_size != 0 {
6267
unsafe {
63-
Global.dealloc(self.ptr.as_ptr() as *mut _,
68+
let c: NonNull<T> = self.ptr.into();
69+
Global.dealloc(c.cast(),
6470
Layout::array::<T>(self.cap).unwrap());
6571
}
6672
}

0 commit comments

Comments
 (0)