@@ -106,6 +106,12 @@ pub struct InferCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
106
106
107
107
pub tables : InferTables < ' a , ' gcx , ' tcx > ,
108
108
109
+ // Cache for projections. This cache is snapshotted along with the
110
+ // infcx.
111
+ //
112
+ // Public so that `traits::project` can use it.
113
+ pub projection_cache : RefCell < traits:: ProjectionCache < ' tcx > > ,
114
+
109
115
// We instantiate UnificationTable with bounds<Ty> because the
110
116
// types that might instantiate a general type variable have an
111
117
// order, represented by its upper and lower bounds.
@@ -479,6 +485,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
479
485
parameter_environment : param_env,
480
486
selection_cache : traits:: SelectionCache :: new ( ) ,
481
487
evaluation_cache : traits:: EvaluationCache :: new ( ) ,
488
+ projection_cache : RefCell :: new ( traits:: ProjectionCache :: new ( ) ) ,
482
489
reported_trait_errors : RefCell :: new ( FnvHashSet ( ) ) ,
483
490
normalize : false ,
484
491
projection_mode : ProjectionMode :: AnyFinal ,
@@ -512,6 +519,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
512
519
global_tcx. enter_local ( arenas, |tcx| f ( InferCtxt {
513
520
tcx : tcx,
514
521
tables : tables,
522
+ projection_cache : RefCell :: new ( traits:: ProjectionCache :: new ( ) ) ,
515
523
type_variables : RefCell :: new ( type_variable:: TypeVariableTable :: new ( ) ) ,
516
524
int_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
517
525
float_unification_table : RefCell :: new ( UnificationTable :: new ( ) ) ,
@@ -547,6 +555,7 @@ impl<'tcx, T> InferOk<'tcx, T> {
547
555
548
556
#[ must_use = "once you start a snapshot, you should always consume it" ]
549
557
pub struct CombinedSnapshot {
558
+ projection_cache_snapshot : traits:: ProjectionCacheSnapshot ,
550
559
type_snapshot : type_variable:: Snapshot ,
551
560
int_snapshot : unify:: Snapshot < ty:: IntVid > ,
552
561
float_snapshot : unify:: Snapshot < ty:: FloatVid > ,
@@ -827,6 +836,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
827
836
self . obligations_in_snapshot . set ( false ) ;
828
837
829
838
CombinedSnapshot {
839
+ projection_cache_snapshot : self . projection_cache . borrow_mut ( ) . snapshot ( ) ,
830
840
type_snapshot : self . type_variables . borrow_mut ( ) . snapshot ( ) ,
831
841
int_snapshot : self . int_unification_table . borrow_mut ( ) . snapshot ( ) ,
832
842
float_snapshot : self . float_unification_table . borrow_mut ( ) . snapshot ( ) ,
@@ -837,7 +847,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
837
847
838
848
fn rollback_to ( & self , cause : & str , snapshot : CombinedSnapshot ) {
839
849
debug ! ( "rollback_to(cause={})" , cause) ;
840
- let CombinedSnapshot { type_snapshot,
850
+ let CombinedSnapshot { projection_cache_snapshot,
851
+ type_snapshot,
841
852
int_snapshot,
842
853
float_snapshot,
843
854
region_vars_snapshot,
@@ -846,6 +857,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
846
857
assert ! ( !self . obligations_in_snapshot. get( ) ) ;
847
858
self . obligations_in_snapshot . set ( obligations_in_snapshot) ;
848
859
860
+ self . projection_cache
861
+ . borrow_mut ( )
862
+ . rollback_to ( projection_cache_snapshot) ;
849
863
self . type_variables
850
864
. borrow_mut ( )
851
865
. rollback_to ( type_snapshot) ;
@@ -861,14 +875,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
861
875
862
876
fn commit_from ( & self , snapshot : CombinedSnapshot ) {
863
877
debug ! ( "commit_from()" ) ;
864
- let CombinedSnapshot { type_snapshot,
878
+ let CombinedSnapshot { projection_cache_snapshot,
879
+ type_snapshot,
865
880
int_snapshot,
866
881
float_snapshot,
867
882
region_vars_snapshot,
868
883
obligations_in_snapshot } = snapshot;
869
884
870
885
self . obligations_in_snapshot . set ( obligations_in_snapshot) ;
871
886
887
+ self . projection_cache
888
+ . borrow_mut ( )
889
+ . commit ( projection_cache_snapshot) ;
872
890
self . type_variables
873
891
. borrow_mut ( )
874
892
. commit ( type_snapshot) ;
@@ -926,7 +944,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
926
944
F : FnOnce ( ) -> Result < T , E >
927
945
{
928
946
debug ! ( "commit_regions_if_ok()" ) ;
929
- let CombinedSnapshot { type_snapshot,
947
+ let CombinedSnapshot { projection_cache_snapshot,
948
+ type_snapshot,
930
949
int_snapshot,
931
950
float_snapshot,
932
951
region_vars_snapshot,
@@ -941,6 +960,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
941
960
942
961
// Roll back any non-region bindings - they should be resolved
943
962
// inside `f`, with, e.g. `resolve_type_vars_if_possible`.
963
+ self . projection_cache
964
+ . borrow_mut ( )
965
+ . rollback_to ( projection_cache_snapshot) ;
944
966
self . type_variables
945
967
. borrow_mut ( )
946
968
. rollback_to ( type_snapshot) ;
0 commit comments