Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic when iterator passed to alloc_extend itself tries to allocate in the same arena #63

Open
lierdakil opened this issue Dec 19, 2023 · 1 comment

Comments

@lierdakil
Copy link

TL;DR: see subject.

A slightly convoluted example:

#[test]
fn test() {
    use typed_arena::Arena;
    enum List<'a> {
        Nil,
        Elt(&'a Self),
        Seq(&'a [Self]),
    }

    let arena: Arena<List> = Arena::new();
    let _ =
        List::Seq(arena.alloc_extend([List::Nil].into_iter().map(|x| List::Elt(arena.alloc(x)))));
}

Expectation: the code works.

Reality:

thread 'test' panicked at 'already borrowed: BorrowMutError', .../typed-arena-2.0.2/src/lib.rs:194:38

For additional context, I wanted to represent a rose-tree-like data structure and save on allocations, constructing it from another data structure, but in effect I have to collect all my iterators into Vecs before alloc_extend and that kinda defeats the purpose.

Now, I understand why it panics. The question is, can we make it not panic? Seems like it should be possible in principle (although tricky)

@lierdakil
Copy link
Author

A simple(-ish) approach may be to change ChunkList::current to be an Option, take it out at the start of alloc_extend. If the iterator tries to allocate, make a new Vec for current. At the end of alloc_extend either put the taken out current back (if current is None) or push it to rest. Depending on the allocation pattern, this may be rather wasteful, but it arguably beats an undocumented panic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant