@@ -8,6 +8,9 @@ use rustc_middle::ty::{self, Ty};
88
99pub use rustc_middle:: traits:: Reveal ;
1010
11+ pub ( crate ) type UndoLog < ' tcx > =
12+ snapshot_map:: UndoLog < ProjectionCacheKey < ' tcx > , ProjectionCacheEntry < ' tcx > > ;
13+
1114#[ derive( Clone ) ]
1215pub struct MismatchedProjectionTypes < ' tcx > {
1316 pub err : ty:: error:: TypeError < ' tcx > ,
@@ -58,9 +61,14 @@ impl<'tcx, T> Normalized<'tcx, T> {
5861//
5962// FIXME: we probably also want some sort of cross-infcx cache here to
6063// reduce the amount of duplication. Let's see what we get with the Chalk reforms.
64+ pub struct ProjectionCache < ' tcx , ' a > {
65+ map : & ' a mut SnapshotMapStorage < ProjectionCacheKey < ' tcx > , ProjectionCacheEntry < ' tcx > > ,
66+ undo_log : & ' a mut Logs < ' tcx > ,
67+ }
68+
6169#[ derive( Default ) ]
62- pub struct ProjectionCache < ' tcx > {
63- map : SnapshotMap < ProjectionCacheKey < ' tcx > , ProjectionCacheEntry < ' tcx > > ,
70+ pub struct ProjectionCacheStorage < ' tcx > {
71+ map : SnapshotMapStorage < ProjectionCacheKey < ' tcx > , ProjectionCacheEntry < ' tcx > > ,
6472}
6573
6674#[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
@@ -82,26 +90,24 @@ pub enum ProjectionCacheEntry<'tcx> {
8290 NormalizedTy ( NormalizedTy < ' tcx > ) ,
8391}
8492
85- // N.B., intentionally not Clone
86- pub struct ProjectionCacheSnapshot {
87- snapshot : Snapshot ,
88- }
89-
90- impl < ' tcx > ProjectionCache < ' tcx > {
91- pub fn clear ( & mut self ) {
92- self . map . clear ( ) ;
93- }
94-
95- pub fn snapshot ( & mut self ) -> ProjectionCacheSnapshot {
96- ProjectionCacheSnapshot { snapshot : self . map . snapshot ( ) }
93+ impl < ' tcx > ProjectionCacheStorage < ' tcx > {
94+ pub ( crate ) fn with_log < ' a > (
95+ & ' a mut self ,
96+ undo_log : & ' a mut Logs < ' tcx > ,
97+ ) -> ProjectionCache < ' tcx , ' a > {
98+ ProjectionCache { map : & mut self . map , undo_log }
9799 }
100+ }
98101
99- pub fn rollback_to ( & mut self , snapshot : ProjectionCacheSnapshot ) {
100- self . map . rollback_to ( snapshot. snapshot ) ;
102+ impl < ' tcx > ProjectionCache < ' tcx , ' _ > {
103+ fn map (
104+ & mut self ,
105+ ) -> SnapshotMapRef < ' _ , ProjectionCacheKey < ' tcx > , ProjectionCacheEntry < ' tcx > , Logs < ' tcx > > {
106+ self . map . with_log ( self . undo_log )
101107 }
102108
103- pub fn commit ( & mut self , snapshot : ProjectionCacheSnapshot ) {
104- self . map . commit ( snapshot . snapshot ) ;
109+ pub fn clear ( & mut self ) {
110+ self . map ( ) . clear ( ) ;
105111 }
106112
107113 /// Try to start normalize `key`; returns an error if
@@ -111,11 +117,12 @@ impl<'tcx> ProjectionCache<'tcx> {
111117 & mut self ,
112118 key : ProjectionCacheKey < ' tcx > ,
113119 ) -> Result < ( ) , ProjectionCacheEntry < ' tcx > > {
114- if let Some ( entry) = self . map . get ( & key) {
120+ let mut map = self . map ( ) ;
121+ if let Some ( entry) = map. get ( & key) {
115122 return Err ( entry. clone ( ) ) ;
116123 }
117124
118- self . map . insert ( key, ProjectionCacheEntry :: InProgress ) ;
125+ map. insert ( key, ProjectionCacheEntry :: InProgress ) ;
119126 Ok ( ( ) )
120127 }
121128
@@ -125,7 +132,7 @@ impl<'tcx> ProjectionCache<'tcx> {
125132 "ProjectionCacheEntry::insert_ty: adding cache entry: key={:?}, value={:?}" ,
126133 key, value
127134 ) ;
128- let fresh_key = self . map . insert ( key, ProjectionCacheEntry :: NormalizedTy ( value) ) ;
135+ let fresh_key = self . map ( ) . insert ( key, ProjectionCacheEntry :: NormalizedTy ( value) ) ;
129136 assert ! ( !fresh_key, "never started projecting `{:?}`" , key) ;
130137 }
131138
@@ -134,7 +141,8 @@ impl<'tcx> ProjectionCache<'tcx> {
134141 /// snapshot - if the snapshot is rolled back, the obligations will be
135142 /// marked as incomplete again).
136143 pub fn complete ( & mut self , key : ProjectionCacheKey < ' tcx > ) {
137- let ty = match self . map . get ( & key) {
144+ let mut map = self . map ( ) ;
145+ let ty = match map. get ( & key) {
138146 Some ( & ProjectionCacheEntry :: NormalizedTy ( ref ty) ) => {
139147 debug ! ( "ProjectionCacheEntry::complete({:?}) - completing {:?}" , key, ty) ;
140148 ty. value
@@ -147,7 +155,7 @@ impl<'tcx> ProjectionCache<'tcx> {
147155 }
148156 } ;
149157
150- self . map . insert (
158+ map. insert (
151159 key,
152160 ProjectionCacheEntry :: NormalizedTy ( Normalized { value : ty, obligations : vec ! [ ] } ) ,
153161 ) ;
@@ -159,7 +167,7 @@ impl<'tcx> ProjectionCache<'tcx> {
159167 // We want to insert `ty` with no obligations. If the existing value
160168 // already has no obligations (as is common) we don't insert anything.
161169 if !ty. obligations . is_empty ( ) {
162- self . map . insert (
170+ self . map ( ) . insert (
163171 key,
164172 ProjectionCacheEntry :: NormalizedTy ( Normalized {
165173 value : ty. value ,
@@ -174,14 +182,20 @@ impl<'tcx> ProjectionCache<'tcx> {
174182 /// type information (in which case, the "fully resolved" key will
175183 /// be different).
176184 pub fn ambiguous ( & mut self , key : ProjectionCacheKey < ' tcx > ) {
177- let fresh = self . map . insert ( key, ProjectionCacheEntry :: Ambiguous ) ;
185+ let fresh = self . map ( ) . insert ( key, ProjectionCacheEntry :: Ambiguous ) ;
178186 assert ! ( !fresh, "never started projecting `{:?}`" , key) ;
179187 }
180188
181189 /// Indicates that trying to normalize `key` resulted in
182190 /// error.
183191 pub fn error ( & mut self , key : ProjectionCacheKey < ' tcx > ) {
184- let fresh = self . map . insert ( key, ProjectionCacheEntry :: Error ) ;
192+ let fresh = self . map ( ) . insert ( key, ProjectionCacheEntry :: Error ) ;
185193 assert ! ( !fresh, "never started projecting `{:?}`" , key) ;
186194 }
187195}
196+
197+ impl < ' tcx > Rollback < UndoLog < ' tcx > > for ProjectionCacheStorage < ' tcx > {
198+ fn reverse ( & mut self , undo : UndoLog < ' tcx > ) {
199+ self . map . reverse ( undo) ;
200+ }
201+ }
0 commit comments