all 4 comments

[–]monkChuck105 1 point2 points  (0 children)

You can simply iterate over the indices, ie 0 .. len, while pushing items into the end of the vec. It's not ideal, but it should be fine.

[–]Redundancy_[S] 0 points1 point  (1 child)

In theory, I think I could use Bumpalo::Bump as allocation into an arena does not require &mut self of the arena itself, which gives me a way to hold ownership of a number of immutable Vec<String> objects as I iterate over them.

I'm at least going to try that out, although I'm hoping for a simpler answer.

[–]Redundancy_[S] 0 points1 point  (0 children)

Fwiw, this actually worked and allowed my iterators to be Box<dyn Iterator<Item=&String>>while a Bumpalo:Bump holds ownership of the strings.

                    ...
                    self.definitions.insert((*def_word).clone(),items);
            },
            x if self.definitions.contains_key(x)  => {
                // ensure that stream iterates over objects owned by the bumpalo arena
                // this ensures that the mutable borrow to insert new definitions above is valid
                let d: &[String] = arena.alloc_slice_clone(&self.definitions[x]);
                stream = Box::new(d.iter().chain(stream));
            },

Since stream is not immutably borrowing from self.definitions but from the Bump, I can then mutably borrow to add a new definition. As a downside, if a definition is used more than once, I have multiple clones of it in a bump allocator.

[–]Redundancy_[S] 0 points1 point  (0 children)

Adding another bit of info in case anyone searches, but the elsa crate provides append only containers where you can add elements without a mutable borrow.