Skip to content

Commit c2583f2

Browse files
committed
---
yaml --- r: 180150 b: refs/heads/tmp c: 2c9d81b h: refs/heads/master v: v3
1 parent d63e04c commit c2583f2

File tree

2 files changed

+45
-22
lines changed

2 files changed

+45
-22
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ refs/heads/building: 126db549b038c84269a1e4fe46f051b2c15d6970
3434
refs/heads/beta: 44a287e6eb22ec3c2a687fc156813577464017f7
3535
refs/heads/windistfix: 7608dbad651f02e837ed05eef3d74a6662a6e928
3636
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
37-
refs/heads/tmp: c1cda0793e4e7b92a73cc13ee6e4a6b14a1b633f
37+
refs/heads/tmp: 2c9d81b2d47d1c8d0e4c771b778238948c269c20

branches/tmp/src/libarena/lib.rs

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,27 +89,29 @@ impl Chunk {
8989
/// than objects without destructors. This reduces overhead when initializing
9090
/// plain-old-data (`Copy` types) and means we don't need to waste time running
9191
/// their destructors.
92-
pub struct Arena {
92+
pub struct Arena<'longer_than_self> {
9393
// The head is separated out from the list as a unbenchmarked
9494
// microoptimization, to avoid needing to case on the list to access the
9595
// head.
9696
head: RefCell<Chunk>,
9797
copy_head: RefCell<Chunk>,
9898
chunks: RefCell<Vec<Chunk>>,
99+
_invariant: marker::InvariantLifetime<'longer_than_self>,
99100
}
100101

101-
impl Arena {
102+
impl<'a> Arena<'a> {
102103
/// Allocates a new Arena with 32 bytes preallocated.
103-
pub fn new() -> Arena {
104+
pub fn new() -> Arena<'a> {
104105
Arena::new_with_size(32)
105106
}
106107

107108
/// Allocates a new Arena with `initial_size` bytes preallocated.
108-
pub fn new_with_size(initial_size: usize) -> Arena {
109+
pub fn new_with_size(initial_size: usize) -> Arena<'a> {
109110
Arena {
110111
head: RefCell::new(chunk(initial_size, false)),
111112
copy_head: RefCell::new(chunk(initial_size, true)),
112113
chunks: RefCell::new(Vec::new()),
114+
_invariant: marker::InvariantLifetime,
113115
}
114116
}
115117
}
@@ -123,7 +125,7 @@ fn chunk(size: usize, is_copy: bool) -> Chunk {
123125
}
124126

125127
#[unsafe_destructor]
126-
impl Drop for Arena {
128+
impl<'longer_than_self> Drop for Arena<'longer_than_self> {
127129
fn drop(&mut self) {
128130
unsafe {
129131
destroy_chunk(&*self.head.borrow());
@@ -181,7 +183,7 @@ fn un_bitpack_tydesc_ptr(p: usize) -> (*const TyDesc, bool) {
181183
((p & !1) as *const TyDesc, p & 1 == 1)
182184
}
183185

184-
impl Arena {
186+
impl<'longer_than_self> Arena<'longer_than_self> {
185187
fn chunk_size(&self) -> usize {
186188
self.copy_head.borrow().capacity()
187189
}
@@ -294,7 +296,7 @@ impl Arena {
294296
/// Allocates a new item in the arena, using `op` to initialize the value,
295297
/// and returns a reference to it.
296298
#[inline]
297-
pub fn alloc<T, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
299+
pub fn alloc<T:'longer_than_self, F>(&self, op: F) -> &mut T where F: FnOnce() -> T {
298300
unsafe {
299301
if intrinsics::needs_drop::<T>() {
300302
self.alloc_noncopy(op)
@@ -318,20 +320,6 @@ fn test_arena_destructors() {
318320
}
319321
}
320322

321-
#[test]
322-
fn test_arena_alloc_nested() {
323-
struct Inner { value: usize }
324-
struct Outer<'a> { inner: &'a Inner }
325-
326-
let arena = Arena::new();
327-
328-
let result = arena.alloc(|| Outer {
329-
inner: arena.alloc(|| Inner { value: 10 })
330-
});
331-
332-
assert_eq!(result.inner.value, 10);
333-
}
334-
335323
#[test]
336324
#[should_fail]
337325
fn test_arena_destructors_fail() {
@@ -529,6 +517,41 @@ mod tests {
529517
z: i32,
530518
}
531519

520+
#[test]
521+
fn test_arena_alloc_nested() {
522+
struct Inner { value: u8 }
523+
struct Outer<'a> { inner: &'a Inner }
524+
enum EI<'e> { I(Inner), O(Outer<'e>) }
525+
526+
struct Wrap<'a>(TypedArena<EI<'a>>);
527+
528+
impl<'a> Wrap<'a> {
529+
fn alloc_inner<F:Fn() -> Inner>(&self, f: F) -> &Inner {
530+
let r: &EI = self.0.alloc(EI::I(f()));
531+
if let &EI::I(ref i) = r {
532+
i
533+
} else {
534+
panic!("mismatch");
535+
}
536+
}
537+
fn alloc_outer<F:Fn() -> Outer<'a>>(&self, f: F) -> &Outer {
538+
let r: &EI = self.0.alloc(EI::O(f()));
539+
if let &EI::O(ref o) = r {
540+
o
541+
} else {
542+
panic!("mismatch");
543+
}
544+
}
545+
}
546+
547+
let arena = Wrap(TypedArena::new());
548+
549+
let result = arena.alloc_outer(|| Outer {
550+
inner: arena.alloc_inner(|| Inner { value: 10 }) });
551+
552+
assert_eq!(result.inner.value, 10);
553+
}
554+
532555
#[test]
533556
pub fn test_copy() {
534557
let arena = TypedArena::new();

0 commit comments

Comments
 (0)