The underlying mechanism of rayon is work stealing. This means that when we call the following function, the current thread will immediately start working on a and place b in a queue:
rayon::join(a, b);
Meanwhile, whenever a core is idle, rayon will let it work on the next task in the queue. The new thread then steals the task from the others. In our case, that would be b. If a happens to finish before b, the main thread will look into the queue and try to steal work as well. The queue can contain more than two items if rayon::join is called multiple times in a recursive function.
The author of rayon, Niko Matsakis, wrote down the following pseudo Rust code to illustrate this principle in his introductory blog post at http://smallcultfollowing.com/babysteps/blog/2015/12/18/rayon-data-parallelism-in-rust/:
fn join<A,B>(oper_a: A, oper_b: B)
where A: FnOnce() + Send,
B: FnOnce() + Send,
{
// Advertise `oper_b` to...