Skip to content

Commit

Permalink
manually outline closure
Browse files Browse the repository at this point in the history
this avoids capturing unused generic parameters, slightly improving
compile times. The performance cost is a lot higher with the
next-generation trait solver which pretty much hangs without this
change.
  • Loading branch information
lcnr authored and Philippe-Cholet committed May 24, 2024
1 parent 2ca3c5a commit ac8fb03
Showing 1 changed file with 14 additions and 2 deletions.
16 changes: 14 additions & 2 deletions src/adaptors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -773,16 +773,28 @@ macro_rules! impl_tuple_combination {
where
F: FnMut(B, Self::Item) -> B,
{
// We outline this closure to prevent it from unnecessarily
// capturing the type parameters `I`, `B`, and `F`. Not doing
// so ended up causing exponentially big types during MIR
// inlining when building itertools with optimizations enabled.
//
// This change causes a small improvement to compile times in
// release mode.
type CurrTuple<A> = (A, $(ignore_ident!($X, A)),*);
type PrevTuple<A> = ($(ignore_ident!($X, A),)*);
fn map_fn<A: Clone>(z: &A) -> impl FnMut(PrevTuple<A>) -> CurrTuple<A> + '_ {
move |($($X,)*)| (z.clone(), $($X),*)
}
let Self { c, item, mut iter } = self;
if let Some(z) = item.as_ref() {
init = c
.map(|($($X,)*)| (z.clone(), $($X),*))
.map(map_fn::<A>(z))
.fold(init, &mut f);
}
while let Some(z) = iter.next() {
let c: $P<I> = iter.clone().into();
init = c
.map(|($($X,)*)| (z.clone(), $($X),*))
.map(map_fn::<A>(&z))
.fold(init, &mut f);
}
init
Expand Down

0 comments on commit ac8fb03

Please sign in to comment.