Report #17258
[bug\_fix] recursion in an \`async fn\` requires boxing \(E0733\) or \`overflow evaluating the requirement\` for recursive async types
Change the return type from \`impl Future\` or \`async fn\` to a boxed future: \`Pin \+ Send \+ 'static>>\` and return \`Box::pin\(async move \{ ... \}\)\`. Alternatively, use the \`async\_recursion\` crate to handle the boxing automatically. Root cause: An \`async fn\` returns an opaque, unique future type for each call. In recursion, the return type would be infinitely large \(the future contains the state of the current call plus the nested future, ad infinitum\). Boxing allocates the nested future on the heap, breaking the infinite size cycle and yielding a concrete, finite \`Box\`.
Journey Context:
You are writing a recursive directory walker using \`tokio::fs\`. You define \`async fn walk\(path: PathBuf\) -> Vec \{ ... \}\`. Inside, you read the directory, and for each subdirectory, you call \`let sub\_entries = walk\(entry.path\(\)\).await;\` and extend the result. The compiler errors with \`error\[E0733\]: recursion in an async fn requires boxing\`. You also see a secondary error about \`overflow evaluating the requirement\`. You search E0733 and find the Rust reference explaining the infinite type size issue. You try to return \`Box::new\(async move \{ ... \}\)\` but it doesn't compile because \`async\` blocks don't implement \`Future\` directly in a way that Box can coerce without \`Pin\`. You read the \`async\` book section on recursion and learn to use \`Pin> \+ Send>>\` as the return type. You change the signature and return \`Box::pin\(async move \{ ... \}\)\` inside. The compiler warns about unused \`async\` in the outer function if you box the inner block, so you make the whole function return the boxed future. You also discover the \`async-recursion\` crate, add it to \`Cargo.toml\`, and simply annotate your original function with \`\#\[async\_recursion\]\`. It compiles and works. You understand that recursion in async Rust requires heap allocation to handle the unknown size of the future at compile time.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T04:51:45.428810+00:00— report_created — created