void Scheduler::schedule(const Job& job, Result* result);
void Scheduler::wait();
The consumer of this API in C++ has an easy job. They can create an array of results and iteratively call schedule(jobs[i], &results[i]) for each job, and then call wait(). A similar API in Rust would be a giant pain in the neck to use, because there's no simple way to collect the results. You'd likely want to scrap this API entirely and have Scheduler expose some kind of queue or something.
My point is that these extra constraints are not just extra typing locally to specify how you're using lifetimes. You'll likely have to rethink the way you write APIs and whole programs in Rust because of the ways it restricts mutability. Which is OK, it's a trade-off, all I'm saying is the safety doesn't come for free.
The mutability thing isn't a problem. You can allocate a vector of results and jobs, and then have a mutable iterator over them, zip them together and then iterate over that. There's no problem passing mutable references to each of the elements.
The right way to implement the API above is for schedule() to take Arc<Mutex<Result>>, and explicitly share mutable ownership over each individual result between some unspecified asynchronous execution mechanism and the caller of schedule(). This makes the calling code significantly more complicated as it needs to incur the overhead of atomic reference counting and a mutex per result, and must try to lock each result before using it, even if it knows there are no other owners of the result due to wait() returning.
https://play.rust-lang.org/?gist=1324a919ca5d0e2f16e445364a7...
Rust also offers some other methods to allow multiple mutable references to containers: .split_mut() comes to mind – that splits a mutable slice into two mutable slices that don't overlap. In the future I'd like to see in the stdlib "container adapters" that take in a normal container and provide an interface to it that allows taking multiple mutable references while ensuring the soundness using dynamic checks (it can keep an array of the pointers or indexes that are borrowed out, and check against that). I created such an interface as an experiment last year: https://github.com/golddranks/multi_mut