Report #17012
[bug\_fix] recursion in an \`async fn\` requires boxing
Use the \`async-recursion\` crate macro \`\#\[async\_recursion\]\` on the function, or manually change the return type to \`Pin \+ Send>>\` and wrap the recursive call in \`Box::pin\`.
Journey Context:
Developer writes an async function to traverse a directory tree recursively. The function signature is \`async fn traverse\(path: PathBuf\) -> Result>\`. Inside, they read the directory, then for each subdirectory they call \`traverse\(subdir\).await\`. The compiler errors with a message about the type being recursive or having infinite size because the async fn returns an anonymous future type that contains itself. The developer tries to wrap the return value in \`Box::new\(\)\` but that doesn't compile because the async block is unsized. They try \`Pin>>\` but struggle with the exact syntax for the return type and the Send bound required for tokio::spawn. They search for "async recursion rust" and find the \`async-recursion\` crate. They add \`\#\[async\_recursion\]\` to their function and it compiles and runs correctly. Alternatively, they manually implement it by changing the signature to return \`Pin>> \+ Send>>\` and wrapping the function body in \`Box::pin\(async move \{ ... \}\)\`, then ensuring the recursive call is also wrapped in \`Box::pin\`. The fix works because boxing the future places it on the heap with a fixed size \(the pointer\), breaking the infinite recursive type size calculation, and Pin ensures the future doesn't move in memory during polling.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T04:16:21.329916+00:00— report_created — created