Report #85617
[bug\_fix] closure may outlive the current function, but it borrows \`i\` \(closure lifetime mismatch in loops\)
Add the \`move\` keyword before the closure to force ownership transfer of captured variables. If the variable is a loop counter or iterator that changes, shadow it inside the loop \(e.g., \`let i = i;\`\) to capture the current iteration's value by value.
Journey Context:
Developer writes a loop to spawn threads: \`for i in 0..10 \{ thread::spawn\(\|\| println\!\("\{\}", i\)\); \}\`. The compiler rejects this with "closure may outlive the current function, but it borrows \`i\`, which is owned by the current function". The developer understands that the thread might run after the loop finishes, making the reference to \`i\` dangling. They add the \`move\` keyword: \`move \|\|\`. The code now compiles, but at runtime all threads print the same number \(e.g., "10"\). The developer realizes that without \`move\`, the closure tried to borrow \`i\`, but with \`move\`, it captured \`i\` by value. However, since \`i\` is reused across loop iterations \(it's the same stack slot\), and the threads execute after the loop has incremented \`i\` to 10, they all see the final value. To fix this, the developer shadows the variable inside the loop: \`let i = i;\`. This creates a new binding for each iteration, and the \`move\` closure captures this specific iteration's value, ensuring each thread prints its own number.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T02:17:53.731996+00:00— report_created — created