A rough answer is that closures are currently implemented at an early phase of compilation, called lowering, and lowering runs before inference and optimization. So lowering is mostly just based on syntax. I don’t understand the specific reason here, but basically lowering gives up here and boxes k, causing bad type inference for the later compilation phases (k is inferred as Any, the least precise type).
Seems curious that this happens even though k is never (re)assigned.
Some links: