Hello! I am having issues with annotating the lifetimes of a function that takes two impl FnOnce
as arguments. This is my use case:
builder.then_build(literal("next"), |builder| {
builder.command(…)
});
The builder
is a structure holding a mutable reference to a TreeGraph
structure.
And literal
is a function returning impl FnOnce
which takes a &'a mut TreeGraph
and returns a new builder structure which is holding the given reference.
This is my original implementation of then_build
:
pub fn then_build<'a, 'b, FB, B, F>(&'a mut self, builder: FB, scope: F)
where
FB: FnOnce(&'b mut TreeGraph<CS, AT, SP, R, M, S, CR>) -> B,
B: Build<Node = CommandNode<CS, AT, SP, R, M, S, CR>> + 'b,
F: FnOnce(&mut B),
'a: 'b,
{
let node = {
let mut b = builder(self.tree);
scope(&mut b);
b.build()
};
self.then(node); // <- Error
}
But I can't borrow self
because self.tree
is still borrowed mutably by builder(self.tree)
.
For more context: This is part of a port of Mojang's Brigadier Java library to Rust; the ArgumentBuilder Class to be precise.
My idea was that the builder
function creates a new builder structure for a kind of node in the graph. This builder borrows the tree of the parent builder mutably. The scope
function then modifies this builder.
When I don't give any lifetimes, the function has no errors, but I cannot use the function because the builder
function cannot return a structure that is storing the given mutable tree reference.
It was recommended to me that I should try something similar to AsyncFnOnce1 in async_fn_traits - Rust, but I cannot get it to work.
I first started this discussion on the Rust Community Discord.