rust-lang / rust-lang/rust-clippy

clippy::large_futures does not fire when the .await comes from a macro expansion (e.g. #[tauri::command])

Open
#17,586 7 comments 0 reactions 1 assignee View on GitHub

@0xull is already working on this.

Since Sep 4, 2026.

I-false-negative
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Summary

clippy::large_futures does not fire when the .await expression is produced by a macro expansion, even though the awaited future is just as large as in the direct-call case. The only difference is whether the .await itself is macro-generated.

Version
clippy 0.1.93 (01f6ddf758 2026-02-11)
rustc 1.93.1 (01f6ddf75 2026-02-11)
Reproduction (no dependencies)
#![allow(dead_code)]

async fn yield_now() {}

async fn big() -> u8 {
    let big = [0u8; 65536];
    yield_now().await;
    big[0]
}

async fn direct_caller() {
    let _v = big().await; // ✔ fires: "large future with a size of 65538 bytes"
}

macro_rules! call_it {
    ($f:expr) => {
        $f.await
    };
}

async fn macro_caller() {
    let _v = call_it!(big()); // ✗ silently passes
}

fn main() {}
cargo clippy -- -W clippy::large_futures

Only direct_caller is flagged. Replacing the macro with a plain .await on the same expression makes the lint fire, so the future size itself is clearly computable in both cases — the from_expansion() guard on the await expression appears to suppress it. The same behavior occurs with a crate-level #![warn(clippy::large_futures)] instead of the command-line flag, and with -D instead of -W.

Not covered by the existing test

The macro_expn case in tests/ui/large_futures.rs does expand a macro, but the macro produces the async block (the future itself) while the .await is hand-written outside the macro (macro_!().await). I verified that running that test file as-is does produce the annotated warnings on this toolchain — but the case where the .await itself comes from macro expansion (future from a clean call site, await generated inside the macro) is not exercised by the test suite.

The from_expansion() exclusion may well be intentional to avoid lint noise inside macros; the problem is that it also exempts the pattern where a framework's macro polls a user-provided future, which is exactly where large futures bite.

Why this matters in practice

Frameworks that poll user futures through macro-generated code are where large futures cause real stack overflows:

  • Tauri's #[tauri::command] on an async fn polls the command future through macro-generated wrapper code. We recently debugged a production crash (0xC00000FD stack overflow on Windows, no logs since the kernel kills the process) caused by a ~329 KB command future blowing up the invoke-dispatch stack frame. The dispatch chain held ~993 KiB of frames in total. Fixed by Box::pin-ing the future inside the command body — but clippy::large_futures never flagged it, because the await point lives inside the macro expansion.
  • In debug builds Tauri itself Box::pins command futures (for faster compiles), so the problem is release-only and invisible during development, which makes a working lint the natural first line of defense.
Meta

Tried variants to rule out other causes: awaiting across an async fn boundary vs. an async block, tokio::spawn, future-size-threshold in clippy.toml (note: changing clippy.toml alone does not invalidate cargo's fingerprint cache — needs a touch on the sources to re-run), a full #[tauri::command] reproduction, and crate-level attributes vs. command-line flags. Direct awaits fire in every variant; macro-expanded awaits never do.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.