Skip to content

Exponential compile time increase when nesting async closures in 1.86 #140004

Open
@lazkindness

Description

@lazkindness

In a library that is chaining together a series of operations, I have it structured roughly like this:

    pub struct PropChain<F> {
        inertia: Inertia,
        props: F,
    }

pub fn prop<F, P, S>(
        self,
        name: &'static str,
        prop: impl Into<PropBuilder<F, S>>, // <-- notice how this holds `F`
    ) -> PropChain<impl Future<Output = Response>>
    where
        Fut: Future<Output = Response>,
        F: AsyncFnOnce() -> P, // <-- which is an async closure
        P: PropControlFlow,
        S: prop_builder::State,
    {
        let prop = prop.into().build();
        let eval = prop
            .eval(name)
            .req_headers(RequestHeaders::from(&self.inertia.header_map))
            .maybe_component(self.inertia.extension.component())
            .method(&self.inertia.method)
            .build();

        let extension = self.inertia.extension_ptr();
        let props = async move {
            let extension = extension.deref();
            if let ControlFlow::Break(err) = eval.apply(name, extension).await { // <-- which is called here, in the request to apply
                return err.into_response();
            }

            self.props.await
        };

        PropChain {
            inertia: self.inertia,
            props, // <-- which is then returning the "wrapped" future
        }
    }

In this code, it's used by calling .prop over and over again passing an async closure to create a stack of futures that will run all at once the response is to be evaluated. I noticed that for each .prop call added, the compile time increases exponentially until it reaches hours.

Additionally, I can confirm that this is happening during the MIR phase of compilation. Cargo check and rust analyzer (as well as a custom rustc driver being used for type generation) all fly through compiling this code, it's only when cargo build is executed that this issue occurs. I found no significant difference when attempting this during release or debug builds.

I have confirmed that this happens in 1.85 (when async closures were stabilized), 1.86, and nightly.

Meta

rustc --version --verbose:

rustc 1.87.0-nightly (617aad8c2 2025-02-24)
binary: rustc
commit-hash: 617aad8c2e8783f6df8e5d1f8bb1e4bcdc70aa7b
commit-date: 2025-02-24
host: aarch64-apple-darwin
release: 1.87.0-nightly
LLVM version: 20.1.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-compiletimeIssue: Problems and improvements with respect to compile times.S-needs-reproStatus: This issue has no reproduction and needs a reproduction to make progress.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions