@@ -3,7 +3,7 @@ use std::ops::ControlFlow;
3
3
use derive_where:: derive_where;
4
4
#[ cfg( feature = "nightly" ) ]
5
5
use 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} ;
7
7
use rustc_type_ir:: fold:: { TypeFoldable , TypeFolder , TypeSuperFoldable } ;
8
8
use rustc_type_ir:: inherent:: * ;
9
9
use rustc_type_ir:: relate:: Relate ;
@@ -579,18 +579,16 @@ where
579
579
580
580
#[ instrument( level = "trace" , skip( self ) ) ]
581
581
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 ) ) ;
585
584
self . inspect . add_normalizes_to_goal ( self . delegate , self . max_input_universe , goal) ;
586
585
self . nested_goals . normalizes_to_goals . push ( goal) ;
587
586
}
588
587
589
588
#[ instrument( level = "debug" , skip( self ) ) ]
590
589
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 ) ) ;
594
592
self . inspect . add_goal ( self . delegate , self . max_input_universe , source, goal) ;
595
593
self . nested_goals . goals . push ( ( source, goal) ) ;
596
594
}
@@ -654,6 +652,7 @@ where
654
652
term : I :: Term ,
655
653
universe_of_term : ty:: UniverseIndex ,
656
654
delegate : & ' a D ,
655
+ cache : HashSet < I :: Ty > ,
657
656
}
658
657
659
658
impl < D : SolverDelegate < Interner = I > , I : Interner > ContainsTermOrNotNameable < ' _ , D , I > {
@@ -671,6 +670,10 @@ where
671
670
{
672
671
type Result = ControlFlow < ( ) > ;
673
672
fn visit_ty ( & mut self , t : I :: Ty ) -> Self :: Result {
673
+ if self . cache . contains ( & t) {
674
+ return ControlFlow :: Continue ( ( ) ) ;
675
+ }
676
+
674
677
match t. kind ( ) {
675
678
ty:: Infer ( ty:: TyVar ( vid) ) => {
676
679
if let ty:: TermKind :: Ty ( term) = self . term . kind ( ) {
@@ -683,17 +686,18 @@ where
683
686
}
684
687
}
685
688
686
- self . check_nameable ( self . delegate . universe_of_ty ( vid) . unwrap ( ) )
689
+ self . check_nameable ( self . delegate . universe_of_ty ( vid) . unwrap ( ) ) ? ;
687
690
}
688
- ty:: Placeholder ( p) => self . check_nameable ( p. universe ( ) ) ,
691
+ ty:: Placeholder ( p) => self . check_nameable ( p. universe ( ) ) ? ,
689
692
_ => {
690
693
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 ) ?
694
695
}
695
696
}
696
697
}
698
+
699
+ assert ! ( self . cache. insert( t) ) ;
700
+ ControlFlow :: Continue ( ( ) )
697
701
}
698
702
699
703
fn visit_const ( & mut self , c : I :: Const ) -> Self :: Result {
@@ -728,6 +732,7 @@ where
728
732
delegate : self . delegate ,
729
733
universe_of_term,
730
734
term : goal. predicate . term ,
735
+ cache : Default :: default ( ) ,
731
736
} ;
732
737
goal. predicate . alias . visit_with ( & mut visitor) . is_continue ( )
733
738
&& goal. param_env . visit_with ( & mut visitor) . is_continue ( )
@@ -1015,6 +1020,17 @@ where
1015
1020
{
1016
1021
ecx : & ' me mut EvalCtxt < ' a , D > ,
1017
1022
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
+ }
1018
1034
}
1019
1035
1020
1036
impl < D , I > TypeFolder < I > for ReplaceAliasWithInfer < ' _ , ' _ , D , I >
@@ -1041,7 +1057,16 @@ where
1041
1057
) ;
1042
1058
infer_ty
1043
1059
}
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,
1045
1070
}
1046
1071
}
1047
1072
0 commit comments