@@ -803,8 +803,7 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for ty::Binder<T> {
803
803
804
804
impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx ty:: List < ty:: ExistentialPredicate < ' tcx > > {
805
805
fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
806
- let v = self . iter ( ) . map ( |p| p. fold_with ( folder) ) . collect :: < SmallVec < [ _ ; 8 ] > > ( ) ;
807
- folder. tcx ( ) . intern_existential_predicates ( & v)
806
+ fold_list ( * self , folder, |tcx, v| tcx. intern_existential_predicates ( v) )
808
807
}
809
808
810
809
fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
@@ -814,8 +813,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::ExistentialPredicate<'tcx>>
814
813
815
814
impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx ty:: List < Ty < ' tcx > > {
816
815
fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
817
- let v = self . iter ( ) . map ( |t| t. fold_with ( folder) ) . collect :: < SmallVec < [ _ ; 8 ] > > ( ) ;
818
- folder. tcx ( ) . intern_type_list ( & v)
816
+ fold_list ( * self , folder, |tcx, v| tcx. intern_type_list ( v) )
819
817
}
820
818
821
819
fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
@@ -825,8 +823,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
825
823
826
824
impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx ty:: List < ProjectionKind > {
827
825
fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
828
- let v = self . iter ( ) . map ( |t| t. fold_with ( folder) ) . collect :: < SmallVec < [ _ ; 8 ] > > ( ) ;
829
- folder. tcx ( ) . intern_projs ( & v)
826
+ fold_list ( * self , folder, |tcx, v| tcx. intern_projs ( v) )
830
827
}
831
828
832
829
fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
@@ -990,17 +987,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region<'tcx> {
990
987
991
988
impl < ' tcx > TypeFoldable < ' tcx > for & ' tcx ty:: List < ty:: Predicate < ' tcx > > {
992
989
fn super_fold_with < F : TypeFolder < ' tcx > > ( & self , folder : & mut F ) -> Self {
993
- // This code is hot enough that it's worth specializing for a list of
994
- // length 0. (No other length is common enough to be worth singling
995
- // out).
996
- if self . len ( ) == 0 {
997
- self
998
- } else {
999
- // Don't bother interning if nothing changed, which is the common
1000
- // case.
1001
- let v = self . iter ( ) . map ( |p| p. fold_with ( folder) ) . collect :: < SmallVec < [ _ ; 8 ] > > ( ) ;
1002
- if v[ ..] == self [ ..] { self } else { folder. tcx ( ) . intern_predicates ( & v) }
1003
- }
990
+ fold_list ( * self , folder, |tcx, v| tcx. intern_predicates ( v) )
1004
991
}
1005
992
1006
993
fn super_visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> bool {
@@ -1073,3 +1060,29 @@ impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> {
1073
1060
false
1074
1061
}
1075
1062
}
1063
+
1064
+ fn fold_list < ' tcx , F , T > (
1065
+ list : & ' tcx ty:: List < T > ,
1066
+ folder : & mut F ,
1067
+ intern : impl FnOnce ( TyCtxt < ' tcx > , & [ T ] ) -> & ' tcx ty:: List < T > ,
1068
+ ) -> & ' tcx ty:: List < T >
1069
+ where
1070
+ F : TypeFolder < ' tcx > ,
1071
+ T : TypeFoldable < ' tcx > + PartialEq + Copy ,
1072
+ {
1073
+ let mut iter = list. iter ( ) ;
1074
+ // Look for the first element that changed
1075
+ if let Some ( ( i, new_t) ) = iter. by_ref ( ) . enumerate ( ) . find_map ( |( i, t) | {
1076
+ let new_t = t. fold_with ( folder) ;
1077
+ if new_t == * t { None } else { Some ( ( i, new_t) ) }
1078
+ } ) {
1079
+ // An element changed, prepare to intern the resulting list
1080
+ let mut new_list = SmallVec :: < [ _ ; 8 ] > :: with_capacity ( list. len ( ) ) ;
1081
+ new_list. copy_from_slice ( & list[ ..i] ) ;
1082
+ new_list. push ( new_t) ;
1083
+ new_list. extend ( iter. map ( |t| t. fold_with ( folder) ) ) ;
1084
+ intern ( folder. tcx ( ) , & new_list)
1085
+ } else {
1086
+ list
1087
+ }
1088
+ }
0 commit comments