1
1
use rustc_hir:: def_id:: DefId ;
2
+ use rustc_index:: IndexVec ;
2
3
use rustc_middle:: ty:: { self , Ty , TyVid } ;
3
4
use rustc_span:: symbol:: Symbol ;
4
5
use rustc_span:: Span ;
@@ -11,14 +12,13 @@ use std::cmp;
11
12
use std:: marker:: PhantomData ;
12
13
use std:: ops:: Range ;
13
14
14
- use rustc_data_structures:: undo_log:: { Rollback , UndoLogs } ;
15
+ use rustc_data_structures:: undo_log:: Rollback ;
15
16
16
17
/// Represents a single undo-able action that affects a type inference variable.
17
18
#[ derive( Clone ) ]
18
19
pub ( crate ) enum UndoLog < ' tcx > {
19
20
EqRelation ( sv:: UndoLog < ut:: Delegate < TyVidEqKey < ' tcx > > > ) ,
20
21
SubRelation ( sv:: UndoLog < ut:: Delegate < ty:: TyVid > > ) ,
21
- Values ( sv:: UndoLog < Delegate > ) ,
22
22
}
23
23
24
24
/// Convert from a specific kind of undo to the more general UndoLog
@@ -35,34 +35,19 @@ impl<'tcx> From<sv::UndoLog<ut::Delegate<ty::TyVid>>> for UndoLog<'tcx> {
35
35
}
36
36
}
37
37
38
- /// Convert from a specific kind of undo to the more general UndoLog
39
- impl < ' tcx > From < sv:: UndoLog < Delegate > > for UndoLog < ' tcx > {
40
- fn from ( l : sv:: UndoLog < Delegate > ) -> Self {
41
- UndoLog :: Values ( l)
42
- }
43
- }
44
-
45
- /// Convert from a specific kind of undo to the more general UndoLog
46
- impl < ' tcx > From < Instantiate > for UndoLog < ' tcx > {
47
- fn from ( l : Instantiate ) -> Self {
48
- UndoLog :: Values ( sv:: UndoLog :: Other ( l) )
49
- }
50
- }
51
-
52
38
impl < ' tcx > Rollback < UndoLog < ' tcx > > for TypeVariableStorage < ' tcx > {
53
39
fn reverse ( & mut self , undo : UndoLog < ' tcx > ) {
54
40
match undo {
55
41
UndoLog :: EqRelation ( undo) => self . eq_relations . reverse ( undo) ,
56
42
UndoLog :: SubRelation ( undo) => self . sub_relations . reverse ( undo) ,
57
- UndoLog :: Values ( undo) => self . values . reverse ( undo) ,
58
43
}
59
44
}
60
45
}
61
46
62
47
#[ derive( Clone ) ]
63
48
pub struct TypeVariableStorage < ' tcx > {
64
- values : sv :: SnapshotVecStorage < Delegate > ,
65
-
49
+ /// The origins of each type variable.
50
+ values : IndexVec < TyVid , TypeVariableData > ,
66
51
/// Two variables are unified in `eq_relations` when we have a
67
52
/// constraint `?X == ?Y`. This table also stores, for each key,
68
53
/// the known value.
@@ -168,15 +153,10 @@ impl<'tcx> TypeVariableValue<'tcx> {
168
153
}
169
154
}
170
155
171
- #[ derive( Clone ) ]
172
- pub ( crate ) struct Instantiate ;
173
-
174
- pub ( crate ) struct Delegate ;
175
-
176
156
impl < ' tcx > TypeVariableStorage < ' tcx > {
177
157
pub fn new ( ) -> TypeVariableStorage < ' tcx > {
178
158
TypeVariableStorage {
179
- values : sv :: SnapshotVecStorage :: new ( ) ,
159
+ values : Default :: default ( ) ,
180
160
eq_relations : ut:: UnificationTableStorage :: new ( ) ,
181
161
sub_relations : ut:: UnificationTableStorage :: new ( ) ,
182
162
}
@@ -194,15 +174,20 @@ impl<'tcx> TypeVariableStorage<'tcx> {
194
174
pub ( crate ) fn eq_relations_ref ( & self ) -> & ut:: UnificationTableStorage < TyVidEqKey < ' tcx > > {
195
175
& self . eq_relations
196
176
}
177
+
178
+ pub ( super ) fn finalize_rollback ( & mut self ) {
179
+ debug_assert ! ( self . values. len( ) >= self . eq_relations. len( ) ) ;
180
+ self . values . truncate ( self . eq_relations . len ( ) ) ;
181
+ }
197
182
}
198
183
199
184
impl < ' tcx > TypeVariableTable < ' _ , ' tcx > {
200
185
/// Returns the origin that was given when `vid` was created.
201
186
///
202
187
/// Note that this function does not return care whether
203
188
/// `vid` has been unified with something else or not.
204
- pub fn var_origin ( & self , vid : ty:: TyVid ) -> & TypeVariableOrigin {
205
- & self . storage . values . get ( vid. as_usize ( ) ) . origin
189
+ pub fn var_origin ( & self , vid : ty:: TyVid ) -> TypeVariableOrigin {
190
+ self . storage . values [ vid] . origin
206
191
}
207
192
208
193
/// Records that `a == b`, depending on `dir`.
@@ -237,11 +222,6 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
237
222
self . eq_relations( ) . probe_value( vid)
238
223
) ;
239
224
self . eq_relations ( ) . union_value ( vid, TypeVariableValue :: Known { value : ty } ) ;
240
-
241
- // Hack: we only need this so that `types_escaping_snapshot`
242
- // can see what has been unified; see the Delegate impl for
243
- // more details.
244
- self . undo_log . push ( Instantiate ) ;
245
225
}
246
226
247
227
/// Creates a new type variable.
@@ -262,14 +242,14 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
262
242
let eq_key = self . eq_relations ( ) . new_key ( TypeVariableValue :: Unknown { universe } ) ;
263
243
264
244
let sub_key = self . sub_relations ( ) . new_key ( ( ) ) ;
265
- assert_eq ! ( eq_key. vid, sub_key) ;
245
+ debug_assert_eq ! ( eq_key. vid, sub_key) ;
266
246
267
- let index = self . values ( ) . push ( TypeVariableData { origin } ) ;
268
- assert_eq ! ( eq_key. vid. as_u32 ( ) , index as u32 ) ;
247
+ let index = self . storage . values . push ( TypeVariableData { origin } ) ;
248
+ debug_assert_eq ! ( eq_key. vid, index) ;
269
249
270
250
debug ! ( "new_var(index={:?}, universe={:?}, origin={:?})" , eq_key. vid, universe, origin) ;
271
251
272
- eq_key . vid
252
+ index
273
253
}
274
254
275
255
/// Returns the number of type variables created thus far.
@@ -329,13 +309,6 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
329
309
}
330
310
}
331
311
332
- #[ inline]
333
- fn values (
334
- & mut self ,
335
- ) -> sv:: SnapshotVec < Delegate , & mut Vec < TypeVariableData > , & mut InferCtxtUndoLogs < ' tcx > > {
336
- self . storage . values . with_log ( self . undo_log )
337
- }
338
-
339
312
#[ inline]
340
313
fn eq_relations ( & mut self ) -> super :: UnificationTable < ' _ , ' tcx , TyVidEqKey < ' tcx > > {
341
314
self . storage . eq_relations . with_log ( self . undo_log )
@@ -354,16 +327,14 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
354
327
let range = TyVid :: from_usize ( value_count) ..TyVid :: from_usize ( self . num_vars ( ) ) ;
355
328
(
356
329
range. start ..range. end ,
357
- ( range. start . as_usize ( ) ..range. end . as_usize ( ) )
358
- . map ( |index| self . storage . values . get ( index) . origin )
359
- . collect ( ) ,
330
+ ( range. start ..range. end ) . map ( |index| self . var_origin ( index) ) . collect ( ) ,
360
331
)
361
332
}
362
333
363
334
/// Returns indices of all variables that are not yet
364
335
/// instantiated.
365
- pub fn unsolved_variables ( & mut self ) -> Vec < ty:: TyVid > {
366
- ( 0 ..self . storage . values . len ( ) )
336
+ pub fn unresolved_variables ( & mut self ) -> Vec < ty:: TyVid > {
337
+ ( 0 ..self . num_vars ( ) )
367
338
. filter_map ( |i| {
368
339
let vid = ty:: TyVid :: from_usize ( i) ;
369
340
match self . probe ( vid) {
@@ -375,26 +346,6 @@ impl<'tcx> TypeVariableTable<'_, 'tcx> {
375
346
}
376
347
}
377
348
378
- impl sv:: SnapshotVecDelegate for Delegate {
379
- type Value = TypeVariableData ;
380
- type Undo = Instantiate ;
381
-
382
- fn reverse ( _values : & mut Vec < TypeVariableData > , _action : Instantiate ) {
383
- // We don't actually have to *do* anything to reverse an
384
- // instantiation; the value for a variable is stored in the
385
- // `eq_relations` and hence its rollback code will handle
386
- // it. In fact, we could *almost* just remove the
387
- // `SnapshotVec` entirely, except that we would have to
388
- // reproduce *some* of its logic, since we want to know which
389
- // type variables have been instantiated since the snapshot
390
- // was started, so we can implement `types_escaping_snapshot`.
391
- //
392
- // (If we extended the `UnificationTable` to let us see which
393
- // values have been unified and so forth, that might also
394
- // suffice.)
395
- }
396
- }
397
-
398
349
///////////////////////////////////////////////////////////////////////////
399
350
400
351
/// These structs (a newtyped TyVid) are used as the unification key
0 commit comments