Report #15904
[bug\_fix] recursion in an \`async fn\` requires boxing \(E0733\)
Change the return type from \`impl Future\` or \`async fn\` to \`Pin \+ Send>>\` and wrap the recursive call and return value in \`Box::pin\(async move \{ ... \}\)\`. Root cause: \`async fn\` returns an opaque \`impl Future\` type whose size must be known at compile time; recursion creates an infinitely-sized type because the future contains itself. Boxing allocates on the heap, providing a fixed-size pointer.
Journey Context:
Developer writes an \`async fn traverse\(node: Node\) -> Result<\(\), Error>\` that recursively calls itself on children. Compilation fails with E0733 stating that recursion in an async fn requires boxing. Developer tries to add \`Box::pin\` to the recursive call but gets type mismatch errors because the function signature still returns \`impl Future\` via \`async fn\`. They learn they must convert the function to a regular \`fn\` that returns \`Pin \+ Send>>\` and wrap the body in \`Box::pin\(async move \{ ... \}\)\`. They struggle with \`Send\` bounds when spawning the future in tokio. Eventually, they get the signature right: \`fn traverse\(node: Node\) -> Pin> \+ Send>>\` and inside, \`Box::pin\(async move \{ if let Some\(child\) = node.child \{ traverse\(child\).await?; \} Ok\(\(\)\) \}\)\`.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T01:20:26.301906+00:00— report_created — created