Skip to content

Commit eee5ffb

Browse files
authored
Merge pull request #31 from Mark-Simulacrum/update-allocators
Update to use the new allocator APIs.
2 parents 794c2d6 + 56d90fa commit eee5ffb

File tree

2 files changed

+25
-53
lines changed

2 files changed

+25
-53
lines changed

src/destructors.md

+12-31
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,19 @@ this is totally fine.
2626
For instance, a custom implementation of `Box` might write `Drop` like this:
2727

2828
```rust
29-
#![feature(alloc, heap_api, unique)]
29+
#![feature(unique, allocator_api)]
3030

31-
extern crate alloc;
32-
33-
use std::ptr::{drop_in_place, Unique};
31+
use std::heap::{Heap, Alloc, Layout};
3432
use std::mem;
35-
36-
use alloc::heap;
33+
use std::ptr::{drop_in_place, Unique};
3734

3835
struct Box<T>{ ptr: Unique<T> }
3936

4037
impl<T> Drop for Box<T> {
4138
fn drop(&mut self) {
4239
unsafe {
4340
drop_in_place(self.ptr.as_ptr());
44-
heap::deallocate(self.ptr.as_ptr() as *mut u8,
45-
mem::size_of::<T>(),
46-
mem::align_of::<T>());
41+
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>())
4742
}
4843
}
4944
}
@@ -57,24 +52,19 @@ use-after-free the `ptr` because when drop exits, it becomes inaccessible.
5752
However this wouldn't work:
5853

5954
```rust
60-
#![feature(alloc, heap_api, unique)]
61-
62-
extern crate alloc;
55+
#![feature(allocator_api, unique)]
6356

57+
use std::heap::{Heap, Alloc, Layout};
6458
use std::ptr::{drop_in_place, Unique};
6559
use std::mem;
6660

67-
use alloc::heap;
68-
6961
struct Box<T>{ ptr: Unique<T> }
7062

7163
impl<T> Drop for Box<T> {
7264
fn drop(&mut self) {
7365
unsafe {
7466
drop_in_place(self.ptr.as_ptr());
75-
heap::deallocate(self.ptr.as_ptr() as *mut u8,
76-
mem::size_of::<T>(),
77-
mem::align_of::<T>());
67+
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>());
7868
}
7969
}
8070
}
@@ -86,9 +76,7 @@ impl<T> Drop for SuperBox<T> {
8676
unsafe {
8777
// Hyper-optimized: deallocate the box's contents for it
8878
// without `drop`ing the contents
89-
heap::deallocate(self.my_box.ptr.as_ptr() as *mut u8,
90-
mem::size_of::<T>(),
91-
mem::align_of::<T>());
79+
Heap.dealloc(self.my_box.ptr.as_ptr() as *mut u8, Layout::new::<T>());
9280
}
9381
}
9482
}
@@ -135,24 +123,19 @@ The classic safe solution to overriding recursive drop and allowing moving out
135123
of Self during `drop` is to use an Option:
136124

137125
```rust
138-
#![feature(alloc, heap_api, unique)]
139-
140-
extern crate alloc;
126+
#![feature(allocator_api, unique)]
141127

128+
use std::heap::{Alloc, Heap, Layout};
142129
use std::ptr::{drop_in_place, Unique};
143130
use std::mem;
144131

145-
use alloc::heap;
146-
147132
struct Box<T>{ ptr: Unique<T> }
148133

149134
impl<T> Drop for Box<T> {
150135
fn drop(&mut self) {
151136
unsafe {
152137
drop_in_place(self.ptr.as_ptr());
153-
heap::deallocate(self.ptr.as_ptr() as *mut u8,
154-
mem::size_of::<T>(),
155-
mem::align_of::<T>());
138+
Heap.dealloc(self.ptr.as_ptr() as *mut u8, Layout::new::<T>());
156139
}
157140
}
158141
}
@@ -166,9 +149,7 @@ impl<T> Drop for SuperBox<T> {
166149
// without `drop`ing the contents. Need to set the `box`
167150
// field as `None` to prevent Rust from trying to Drop it.
168151
let my_box = self.my_box.take().unwrap();
169-
heap::deallocate(my_box.ptr.as_ptr() as *mut u8,
170-
mem::size_of::<T>(),
171-
mem::align_of::<T>());
152+
Heap.dealloc(my_box.ptr.as_ptr() as *mut u8, Layout::new::<T>());
172153
mem::forget(my_box);
173154
}
174155
}

src/vec-final.md

+13-22
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,13 @@
22

33
```rust
44
#![feature(unique)]
5-
#![feature(alloc, heap_api)]
6-
7-
extern crate alloc;
5+
#![feature(allocator_api)]
86

97
use std::ptr::{Unique, self};
108
use std::mem;
119
use std::ops::{Deref, DerefMut};
1210
use std::marker::PhantomData;
13-
14-
use alloc::heap;
11+
use std::heap::{Alloc, Layout, Heap};
1512

1613
struct RawVec<T> {
1714
ptr: Unique<T>,
@@ -35,22 +32,22 @@ impl<T> RawVec<T> {
3532
// 0, getting to here necessarily means the Vec is overfull.
3633
assert!(elem_size != 0, "capacity overflow");
3734

38-
let align = mem::align_of::<T>();
39-
4035
let (new_cap, ptr) = if self.cap == 0 {
41-
let ptr = heap::allocate(elem_size, align);
36+
let ptr = Heap.alloc(Layout::array::<T>(1).unwrap());
4237
(1, ptr)
4338
} else {
4439
let new_cap = 2 * self.cap;
45-
let ptr = heap::reallocate(self.ptr.as_ptr() as *mut _,
46-
self.cap * elem_size,
47-
new_cap * elem_size,
48-
align);
40+
let ptr = Heap.realloc(self.ptr.as_ptr() as *mut _,
41+
Layout::array::<T>(self.cap).unwrap(),
42+
Layout::array::<T>(new_cap).unwrap());
4943
(new_cap, ptr)
5044
};
5145

52-
// If allocate or reallocate fail, we'll get `null` back
53-
if ptr.is_null() { oom() }
46+
// If allocate or reallocate fail, oom
47+
let ptr = match ptr {
48+
Ok(ptr) => ptr,
49+
Err(err) => Heap.oom(err),
50+
};
5451

5552
self.ptr = Unique::new(ptr as *mut _);
5653
self.cap = new_cap;
@@ -62,20 +59,14 @@ impl<T> Drop for RawVec<T> {
6259
fn drop(&mut self) {
6360
let elem_size = mem::size_of::<T>();
6461
if self.cap != 0 && elem_size != 0 {
65-
let align = mem::align_of::<T>();
66-
67-
let num_bytes = elem_size * self.cap;
6862
unsafe {
69-
heap::deallocate(self.ptr.as_ptr() as *mut _, num_bytes, align);
63+
Heap.dealloc(self.ptr.as_ptr() as *mut _,
64+
Layout::array::<T>(self.cap).unwrap());
7065
}
7166
}
7267
}
7368
}
7469

75-
76-
77-
78-
7970
pub struct Vec<T> {
8071
buf: RawVec<T>,
8172
len: usize,

0 commit comments

Comments
 (0)