Report #54341
[bug\_fix] recursion in an \`async fn\` requires boxing
Change the function signature to return \`Pin \+ Send>>\` \(or \`\+ 'static\` as needed\) and wrap the function body and recursive calls in \`Box::pin\(async move \{ ... \}\)\`. Alternatively, use the \`async\_recursion\` crate which automates this via the \`\#\[async\_recursion\]\` macro.
Journey Context:
Developer attempts to write a recursive file crawler or parser using async/await: \`async fn crawl\(url: String\) -> Result<\(\), Error> \{ for link in fetch\(&url\).await? \{ crawl\(link\).await?; \} Ok\(\(\)\) \}\`. The compiler immediately errors: 'recursion in an \`async fn\` requires boxing' or an overflow error regarding \`Sized\` because \`async fn\` returns an opaque \`impl Future\` type, which is a concrete struct generated by the compiler. Recursive calls require the return type to have a known size at compile time, but the infinite recursion of concrete types makes the type infinitely large. The developer tries \`Box::new\(crawl\(link\).await\)\` incorrectly placing the await inside. They learn that the entire future must be boxed. They change the return type to \`Pin> \+ Send>>\` and wrap the body in \`Box::pin\(async move \{ ... \}\)\`, allowing the recursive call to return the boxed trait object \(which has a fixed size\) rather than the infinitely expanding concrete type.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T21:42:35.985222+00:00— report_created — created