@@ -3,7 +3,7 @@ use std::ops::ControlFlow;
33use derive_where:: derive_where;
44#[ cfg( feature = "nightly" ) ]
55use rustc_macros:: { HashStable_NoContext , TyDecodable , TyEncodable } ;
6- use rustc_type_ir:: data_structures:: ensure_sufficient_stack;
6+ use rustc_type_ir:: data_structures:: { HashMap , HashSet , ensure_sufficient_stack} ;
77use rustc_type_ir:: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable } ;
88use rustc_type_ir:: inherent:: * ;
99use rustc_type_ir:: relate:: Relate ;
@@ -579,18 +579,16 @@ where
579579
580580 #[ instrument( level = "trace" , skip( self ) ) ]
581581 pub ( super ) fn add_normalizes_to_goal ( & mut self , mut goal : Goal < I , ty:: NormalizesTo < I > > ) {
582- goal. predicate = goal
583- . predicate
584- . fold_with ( & mut ReplaceAliasWithInfer { ecx : self , param_env : goal. param_env } ) ;
582+ goal. predicate =
583+ goal. predicate . fold_with ( & mut ReplaceAliasWithInfer :: new ( self , goal. param_env ) ) ;
585584 self . inspect . add_normalizes_to_goal ( self . delegate , self . max_input_universe , goal) ;
586585 self . nested_goals . normalizes_to_goals . push ( goal) ;
587586 }
588587
589588 #[ instrument( level = "debug" , skip( self ) ) ]
590589 pub ( super ) fn add_goal ( & mut self , source : GoalSource , mut goal : Goal < I , I :: Predicate > ) {
591- goal. predicate = goal
592- . predicate
593- . fold_with ( & mut ReplaceAliasWithInfer { ecx : self , param_env : goal. param_env } ) ;
590+ goal. predicate =
591+ goal. predicate . fold_with ( & mut ReplaceAliasWithInfer :: new ( self , goal. param_env ) ) ;
594592 self . inspect . add_goal ( self . delegate , self . max_input_universe , source, goal) ;
595593 self . nested_goals . goals . push ( ( source, goal) ) ;
596594 }
@@ -654,6 +652,7 @@ where
654652 term : I :: Term ,
655653 universe_of_term : ty:: UniverseIndex ,
656654 delegate : & ' a D ,
655+ cache : HashSet < I :: Ty > ,
657656 }
658657
659658 impl < D : SolverDelegate < Interner = I > , I : Interner > ContainsTermOrNotNameable < ' _ , D , I > {
@@ -671,6 +670,10 @@ where
671670 {
672671 type Result = ControlFlow < ( ) > ;
673672 fn visit_ty ( & mut self , t : I :: Ty ) -> Self :: Result {
673+ if self . cache . contains ( & t) {
674+ return ControlFlow :: Continue ( ( ) ) ;
675+ }
676+
674677 match t. kind ( ) {
675678 ty:: Infer ( ty:: TyVar ( vid) ) => {
676679 if let ty:: TermKind :: Ty ( term) = self . term . kind ( ) {
@@ -683,17 +686,18 @@ where
683686 }
684687 }
685688
686- self . check_nameable ( self . delegate . universe_of_ty ( vid) . unwrap ( ) )
689+ self . check_nameable ( self . delegate . universe_of_ty ( vid) . unwrap ( ) ) ? ;
687690 }
688- ty:: Placeholder ( p) => self . check_nameable ( p. universe ( ) ) ,
691+ ty:: Placeholder ( p) => self . check_nameable ( p. universe ( ) ) ? ,
689692 _ => {
690693 if t. has_non_region_infer ( ) || t. has_placeholders ( ) {
691- t. super_visit_with ( self )
692- } else {
693- ControlFlow :: Continue ( ( ) )
694+ t. super_visit_with ( self ) ?
694695 }
695696 }
696697 }
698+
699+ assert ! ( self . cache. insert( t) ) ;
700+ ControlFlow :: Continue ( ( ) )
697701 }
698702
699703 fn visit_const ( & mut self , c : I :: Const ) -> Self :: Result {
@@ -728,6 +732,7 @@ where
728732 delegate : self . delegate ,
729733 universe_of_term,
730734 term : goal. predicate . term ,
735+ cache : Default :: default ( ) ,
731736 } ;
732737 goal. predicate . alias . visit_with ( & mut visitor) . is_continue ( )
733738 && goal. param_env . visit_with ( & mut visitor) . is_continue ( )
@@ -1015,6 +1020,17 @@ where
10151020{
10161021 ecx : & ' me mut EvalCtxt < ' a , D > ,
10171022 param_env : I :: ParamEnv ,
1023+ cache : HashMap < I :: Ty , I :: Ty > ,
1024+ }
1025+
1026+ impl < ' me , ' a , D , I > ReplaceAliasWithInfer < ' me , ' a , D , I >
1027+ where
1028+ D : SolverDelegate < Interner = I > ,
1029+ I : Interner ,
1030+ {
1031+ fn new ( ecx : & ' me mut EvalCtxt < ' a , D > , param_env : I :: ParamEnv ) -> Self {
1032+ ReplaceAliasWithInfer { ecx, param_env, cache : Default :: default ( ) }
1033+ }
10181034}
10191035
10201036impl < D , I > TypeFolder < I > for ReplaceAliasWithInfer < ' _ , ' _ , D , I >
@@ -1041,7 +1057,16 @@ where
10411057 ) ;
10421058 infer_ty
10431059 }
1044- _ => ty. super_fold_with ( self ) ,
1060+ _ if ty. has_aliases ( ) => {
1061+ if let Some ( & entry) = self . cache . get ( & ty) {
1062+ return entry;
1063+ }
1064+
1065+ let res = ty. super_fold_with ( self ) ;
1066+ assert ! ( self . cache. insert( ty, res) . is_none( ) ) ;
1067+ res
1068+ }
1069+ _ => ty,
10451070 }
10461071 }
10471072
0 commit comments