Skip to content

Commit 758f4e7

Browse files
committed
optimize TypeFoldable for 2 element tuples
1 parent 7d5d6c0 commit 758f4e7

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

compiler/rustc_middle/src/ty/structural_impls.rs

-13
Original file line numberDiff line numberDiff line change
@@ -889,19 +889,6 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::Existentia
889889
}
890890
}
891891

892-
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
893-
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
894-
self,
895-
folder: &mut F,
896-
) -> Result<Self, F::Error> {
897-
ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v))
898-
}
899-
900-
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
901-
self.iter().try_for_each(|t| t.visit_with(visitor))
902-
}
903-
}
904-
905892
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ProjectionKind> {
906893
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
907894
self,

compiler/rustc_middle/src/ty/subst.rs

+39
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,45 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> {
458458
}
459459
}
460460

461+
impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
462+
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
463+
self,
464+
folder: &mut F,
465+
) -> Result<Self, F::Error> {
466+
// This code is fairly hot, though not as hot as `SubstsRef`.
467+
//
468+
// When compiling stage 2, I get the following results:
469+
//
470+
// len | total | %
471+
// --- | --------- | -----
472+
// 2 | 15083590 | 48.1
473+
// 3 | 7540067 | 24.0
474+
// 1 | 5300377 | 16.9
475+
// 4 | 1351897 | 4.3
476+
// 0 | 1256849 | 4.0
477+
//
478+
// I've tried it with some private repositories and got
479+
// close to the same result, with 4 and 0 swapping places
480+
// sometimes.
481+
match self.len() {
482+
2 => {
483+
let param0 = self[0].try_fold_with(folder)?;
484+
let param1 = self[1].try_fold_with(folder)?;
485+
if param0 == self[0] && param1 == self[1] {
486+
Ok(self)
487+
} else {
488+
Ok(folder.tcx().intern_type_list(&[param0, param1]))
489+
}
490+
}
491+
_ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)),
492+
}
493+
}
494+
495+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
496+
self.iter().try_for_each(|t| t.visit_with(visitor))
497+
}
498+
}
499+
461500
///////////////////////////////////////////////////////////////////////////
462501
// Public trait `Subst`
463502
//

0 commit comments

Comments
 (0)