I have a code similar to the following; essentially, I run a bunch of computation in parallel based on values from the initial context, aggregates the results, then once I got everything back I update the context with the new values.
However the compiler is refusing to let me save the new values into the context, pretexting I already have mutable borrows of the context. That's true, I have references to the context in my futures to avoid having to clone it, but since the futures are guaranteed to have completed by the time I write the result back, my understanding is that the mutable borrow is safe.
Is there a clean way to let the compiler know? I tried drop(self)
and drop(self.running)
to no avail.
use futures::{future::BoxFuture, stream::FuturesUnordered, StreamExt};
struct Foo {
pub base_value: u32,
pub values: std::collections::HashMap<u32, u32>,
}
struct Bar<'a> {
pub running: FuturesUnordered<BoxFuture<'a, (u32, u32)>>,
}
impl<'a> Bar<'a> {
pub fn schedule(&mut self, foo: &'a Foo, n: u32) {
self.running.push(Box::pin(async move {
(n, foo.base_value + n)
}));
}
pub async fn run(mut self, foo: &'a mut Foo) {
let mut values = foo.values.clone();
self.schedule(foo, 1);
self.schedule(foo, 10);
while let Some((n, updated_n)) = self.running.next().await {
values.insert(n, updated_n);
}
// Why isn't 'drop' here telling the compiler that the borrows
// are done? Also tried 'drop(self.running)'
drop(self);
foo.values = values;
}
}
fn main() {}