Description
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