Is there a further specification of how the compiler infers whether to capture the outer variables by reference, copy them or move them? What are the evaluation criteria, and what is their order of application? Is this documented (short of reading the compiler's code)?

Let me complement Francis' answer:

Closures like |x| a*x+b are always capturing their surroundings (like a and b here) by reference. In your case, these are function-local variables and Rust prevents you from returning such a closure because these function-local variables wouldn't exist anymore. Let's thank the borrow checker for catching this mistake. The use cases for these closures is typically passing them as parameters to other functions, not returning them. However, if you don't access any other variables, such a closure is allowed to outlive the scope of the function it was created in: ||:'static -> SomeType . The representation of these closures is just a pair of pointers. One that points to the function and one that points into the function's stack frame (if something was captures by reference).

Closures you write with proc always capture their surroundings by "acquiring" them (they get moved into the closure object's state). Another property of these kinds of closures is that you can only invoke them once because the associated function actually consumes the closure's state. This is useful for launching concurrent tasks. proc closures incure a heap allocation cost because they store their state indirectly (similar to what Box does). The advantage of this is that the representation of proc closures (ignoring the boxed state) is just a pair of pointers. One pointer to the function and one pointer to the boxed variables.