@@ -19,7 +19,6 @@ use middle::infer::InferCtxt;
19
19
use std:: cell:: RefCell ;
20
20
use std:: fmt:: Debug ;
21
21
use syntax:: ast;
22
- use util:: ppaux:: Repr ;
23
22
use util:: snapshot_vec as sv;
24
23
25
24
/// This trait is implemented by any type that can serve as a type
@@ -32,15 +31,17 @@ use util::snapshot_vec as sv;
32
31
/// (possibly not yet known) sort of integer.
33
32
///
34
33
/// Implementations of this trait are at the end of this file.
35
- pub trait UnifyKey < ' tcx , V > : Clone + Debug + PartialEq + Repr < ' tcx > {
34
+ pub trait UnifyKey : Clone + Debug + PartialEq {
35
+ type Value : UnifyValue ;
36
+
36
37
fn index ( & self ) -> uint ;
37
38
38
39
fn from_index ( u : uint ) -> Self ;
39
40
40
41
// Given an inference context, returns the unification table
41
42
// appropriate to this key type.
42
43
fn unification_table < ' v > ( infcx : & ' v InferCtxt )
43
- -> & ' v RefCell < UnificationTable < Self , V > > ;
44
+ -> & ' v RefCell < UnificationTable < Self > > ;
44
45
45
46
fn tag ( k : Option < Self > ) -> & ' static str ;
46
47
}
@@ -51,7 +52,7 @@ pub trait UnifyKey<'tcx, V> : Clone + Debug + PartialEq + Repr<'tcx> {
51
52
/// whose value is not yet set).
52
53
///
53
54
/// Implementations of this trait are at the end of this file.
54
- pub trait UnifyValue < ' tcx > : Clone + Repr < ' tcx > + PartialEq {
55
+ pub trait UnifyValue : Clone + PartialEq + Debug {
55
56
}
56
57
57
58
/// Value of a unification key. We implement Tarjan's union-find
@@ -62,44 +63,44 @@ pub trait UnifyValue<'tcx> : Clone + Repr<'tcx> + PartialEq {
62
63
/// to keep the DAG relatively balanced, which helps keep the running
63
64
/// time of the algorithm under control. For more information, see
64
65
/// <http://en.wikipedia.org/wiki/Disjoint-set_data_structure>.
65
- #[ derive( PartialEq , Clone ) ]
66
- pub enum VarValue < K , V > {
66
+ #[ derive( PartialEq , Clone , Show ) ]
67
+ pub enum VarValue < K : UnifyKey > {
67
68
Redirect ( K ) ,
68
- Root ( V , uint ) ,
69
+ Root ( K :: Value , uint ) ,
69
70
}
70
71
71
72
/// Table of unification keys and their values.
72
- pub struct UnificationTable < K , V > {
73
+ pub struct UnificationTable < K : UnifyKey > {
73
74
/// Indicates the current value of each key.
74
- values : sv:: SnapshotVec < VarValue < K , V > , ( ) , Delegate > ,
75
+ values : sv:: SnapshotVec < Delegate < K > > ,
75
76
}
76
77
77
78
/// At any time, users may snapshot a unification table. The changes
78
79
/// made during the snapshot may either be *committed* or *rolled back*.
79
- pub struct Snapshot < K > {
80
+ pub struct Snapshot < K : UnifyKey > {
80
81
// Link snapshot to the key type `K` of the table.
81
82
marker : marker:: CovariantType < K > ,
82
83
snapshot : sv:: Snapshot ,
83
84
}
84
85
85
86
/// Internal type used to represent the result of a `get()` operation.
86
87
/// Conveys the current root and value of the key.
87
- pub struct Node < K , V > {
88
+ pub struct Node < K : UnifyKey > {
88
89
pub key : K ,
89
- pub value : V ,
90
+ pub value : K :: Value ,
90
91
pub rank : uint ,
91
92
}
92
93
93
94
#[ derive( Copy ) ]
94
- pub struct Delegate ;
95
+ pub struct Delegate < K > ;
95
96
96
97
// We can't use V:LatticeValue, much as I would like to,
97
98
// because frequently the pattern is that V=Option<U> for some
98
99
// other type parameter U, and we have no way to say
99
100
// Option<U>:LatticeValue.
100
101
101
- impl < ' tcx , V : PartialEq + Clone + Repr < ' tcx > , K : UnifyKey < ' tcx , V > > UnificationTable < K , V > {
102
- pub fn new ( ) -> UnificationTable < K , V > {
102
+ impl < K : UnifyKey > UnificationTable < K > {
103
+ pub fn new ( ) -> UnificationTable < K > {
103
104
UnificationTable {
104
105
values : sv:: SnapshotVec :: new ( Delegate ) ,
105
106
}
@@ -126,7 +127,7 @@ impl<'tcx, V:PartialEq+Clone+Repr<'tcx>, K:UnifyKey<'tcx, V>> UnificationTable<K
126
127
self . values . commit ( snapshot. snapshot ) ;
127
128
}
128
129
129
- pub fn new_key ( & mut self , value : V ) -> K {
130
+ pub fn new_key ( & mut self , value : K :: Value ) -> K {
130
131
let index = self . values . push ( Root ( value, 0 ) ) ;
131
132
let k = UnifyKey :: from_index ( index) ;
132
133
debug ! ( "{}: created new key: {:?}" ,
@@ -137,12 +138,12 @@ impl<'tcx, V:PartialEq+Clone+Repr<'tcx>, K:UnifyKey<'tcx, V>> UnificationTable<K
137
138
138
139
/// Find the root node for `vid`. This uses the standard union-find algorithm with path
139
140
/// compression: http://en.wikipedia.org/wiki/Disjoint-set_data_structure
140
- pub fn get ( & mut self , tcx : & ty:: ctxt , vid : K ) -> Node < K , V > {
141
+ pub fn get ( & mut self , tcx : & ty:: ctxt , vid : K ) -> Node < K > {
141
142
let index = vid. index ( ) ;
142
143
let value = ( * self . values . get ( index) ) . clone ( ) ;
143
144
match value {
144
145
Redirect ( redirect) => {
145
- let node: Node < K , V > = self . get ( tcx, redirect. clone ( ) ) ;
146
+ let node: Node < K > = self . get ( tcx, redirect. clone ( ) ) ;
146
147
if node. key != redirect {
147
148
// Path compression
148
149
self . values . set ( index, Redirect ( node. key . clone ( ) ) ) ;
@@ -164,33 +165,32 @@ impl<'tcx, V:PartialEq+Clone+Repr<'tcx>, K:UnifyKey<'tcx, V>> UnificationTable<K
164
165
165
166
/// Sets the value for `vid` to `new_value`. `vid` MUST be a root node! Also, we must be in the
166
167
/// middle of a snapshot.
167
- pub fn set ( & mut self ,
168
- tcx : & ty:: ctxt < ' tcx > ,
169
- key : K ,
170
- new_value : VarValue < K , V > )
168
+ pub fn set < ' tcx > ( & mut self ,
169
+ _tcx : & ty:: ctxt < ' tcx > ,
170
+ key : K ,
171
+ new_value : VarValue < K > )
171
172
{
172
173
assert ! ( self . is_root( & key) ) ;
173
174
174
- debug ! ( "Updating variable {} to {}" ,
175
- key. repr( tcx) ,
176
- new_value. repr( tcx) ) ;
175
+ debug ! ( "Updating variable {:?} to {:?}" ,
176
+ key, new_value) ;
177
177
178
178
self . values . set ( key. index ( ) , new_value) ;
179
179
}
180
180
181
181
/// Either redirects node_a to node_b or vice versa, depending on the relative rank. Returns
182
182
/// the new root and rank. You should then update the value of the new root to something
183
183
/// suitable.
184
- pub fn unify ( & mut self ,
185
- tcx : & ty:: ctxt < ' tcx > ,
186
- node_a : & Node < K , V > ,
187
- node_b : & Node < K , V > )
188
- -> ( K , uint )
184
+ pub fn unify < ' tcx > ( & mut self ,
185
+ tcx : & ty:: ctxt < ' tcx > ,
186
+ node_a : & Node < K > ,
187
+ node_b : & Node < K > )
188
+ -> ( K , uint )
189
189
{
190
- debug ! ( "unify(node_a(id={}, rank={}), node_b(id={}, rank={}))" ,
191
- node_a. key. repr ( tcx ) ,
190
+ debug ! ( "unify(node_a(id={:? }, rank={:? }), node_b(id={:? }, rank={:? }))" ,
191
+ node_a. key,
192
192
node_a. rank,
193
- node_b. key. repr ( tcx ) ,
193
+ node_b. key,
194
194
node_b. rank) ;
195
195
196
196
if node_a. rank > node_b. rank {
@@ -212,8 +212,11 @@ impl<'tcx, V:PartialEq+Clone+Repr<'tcx>, K:UnifyKey<'tcx, V>> UnificationTable<K
212
212
}
213
213
}
214
214
215
- impl < K , V > sv:: SnapshotVecDelegate < VarValue < K , V > , ( ) > for Delegate {
216
- fn reverse ( & mut self , _: & mut Vec < VarValue < K , V > > , _: ( ) ) {
215
+ impl < K > sv:: SnapshotVecDelegate for Delegate < K > {
216
+ type Value = VarValue < K > ;
217
+ type Undo = ( ) ;
218
+
219
+ fn reverse ( & mut self , _: & mut Vec < VarValue < K > > , _: ( ) ) {
217
220
panic ! ( "Nothing to reverse" ) ;
218
221
}
219
222
}
@@ -224,7 +227,7 @@ impl<K,V> sv::SnapshotVecDelegate<VarValue<K,V>,()> for Delegate {
224
227
225
228
/// Indicates a type that does not have any kind of subtyping
226
229
/// relationship.
227
- pub trait SimplyUnifiable < ' tcx > : Clone + PartialEq + Repr < ' tcx > {
230
+ pub trait SimplyUnifiable < ' tcx > : Clone + PartialEq + Debug {
228
231
fn to_type ( & self , tcx : & ty:: ctxt < ' tcx > ) -> Ty < ' tcx > ;
229
232
fn to_type_err ( expected_found < Self > ) -> ty:: type_err < ' tcx > ;
230
233
}
@@ -242,8 +245,11 @@ pub fn err<'tcx, V:SimplyUnifiable<'tcx>>(a_is_expected: bool,
242
245
}
243
246
}
244
247
245
- pub trait InferCtxtMethodsForSimplyUnifiableTypes < ' tcx , V : SimplyUnifiable < ' tcx > ,
246
- K : UnifyKey < ' tcx , Option < V > > > {
248
+ pub trait InferCtxtMethodsForSimplyUnifiableTypes < ' tcx , K , V >
249
+ where K : UnifyKey < Value =Option < V > > ,
250
+ V : SimplyUnifiable < ' tcx > ,
251
+ Option < V > : UnifyValue ,
252
+ {
247
253
fn simple_vars ( & self ,
248
254
a_is_expected : bool ,
249
255
a_id : K ,
@@ -257,8 +263,10 @@ pub trait InferCtxtMethodsForSimplyUnifiableTypes<'tcx, V:SimplyUnifiable<'tcx>,
257
263
fn probe_var ( & self , a_id : K ) -> Option < Ty < ' tcx > > ;
258
264
}
259
265
260
- impl < ' a , ' tcx , V : SimplyUnifiable < ' tcx > , K : UnifyKey < ' tcx , Option < V > > >
261
- InferCtxtMethodsForSimplyUnifiableTypes < ' tcx , V , K > for InferCtxt < ' a , ' tcx >
266
+ impl < ' a , ' tcx , V , K > InferCtxtMethodsForSimplyUnifiableTypes < ' tcx , K , V > for InferCtxt < ' a , ' tcx >
267
+ where K : UnifyKey < Value =Option < V > > ,
268
+ V : SimplyUnifiable < ' tcx > ,
269
+ Option < V > : UnifyValue ,
262
270
{
263
271
/// Unifies two simple keys. Because simple keys do not have any subtyping relationships, if
264
272
/// both keys have already been associated with a value, then those two values must be the
@@ -271,8 +279,8 @@ impl<'a,'tcx,V:SimplyUnifiable<'tcx>,K:UnifyKey<'tcx, Option<V>>>
271
279
{
272
280
let tcx = self . tcx ;
273
281
let table = UnifyKey :: unification_table ( self ) ;
274
- let node_a = table. borrow_mut ( ) . get ( tcx, a_id) ;
275
- let node_b = table. borrow_mut ( ) . get ( tcx, b_id) ;
282
+ let node_a: Node < K > = table. borrow_mut ( ) . get ( tcx, a_id) ;
283
+ let node_b: Node < K > = table. borrow_mut ( ) . get ( tcx, b_id) ;
276
284
let a_id = node_a. key . clone ( ) ;
277
285
let b_id = node_b. key . clone ( ) ;
278
286
@@ -346,14 +354,14 @@ impl<'a,'tcx,V:SimplyUnifiable<'tcx>,K:UnifyKey<'tcx, Option<V>>>
346
354
347
355
// Integral type keys
348
356
349
- impl < ' tcx > UnifyKey < ' tcx , Option < IntVarValue > > for ty:: IntVid {
357
+ impl UnifyKey for ty:: IntVid {
358
+ type Value = Option < IntVarValue > ;
359
+
350
360
fn index ( & self ) -> uint { self . index as uint }
351
361
352
362
fn from_index ( i : uint ) -> ty:: IntVid { ty:: IntVid { index : i as u32 } }
353
363
354
- fn unification_table < ' v > ( infcx : & ' v InferCtxt )
355
- -> & ' v RefCell < UnificationTable < ty:: IntVid , Option < IntVarValue > > >
356
- {
364
+ fn unification_table < ' v > ( infcx : & ' v InferCtxt ) -> & ' v RefCell < UnificationTable < ty:: IntVid > > {
357
365
return & infcx. int_unification_table ;
358
366
}
359
367
@@ -375,18 +383,18 @@ impl<'tcx> SimplyUnifiable<'tcx> for IntVarValue {
375
383
}
376
384
}
377
385
378
- impl < ' tcx > UnifyValue < ' tcx > for Option < IntVarValue > { }
386
+ impl UnifyValue for Option < IntVarValue > { }
379
387
380
388
// Floating point type keys
381
389
382
- impl < ' tcx > UnifyKey < ' tcx , Option < ast:: FloatTy > > for ty:: FloatVid {
390
+ impl UnifyKey for ty:: FloatVid {
391
+ type Value = Option < ast:: FloatTy > ;
392
+
383
393
fn index ( & self ) -> uint { self . index as uint }
384
394
385
395
fn from_index ( i : uint ) -> ty:: FloatVid { ty:: FloatVid { index : i as u32 } }
386
396
387
- fn unification_table < ' v > ( infcx : & ' v InferCtxt )
388
- -> & ' v RefCell < UnificationTable < ty:: FloatVid , Option < ast:: FloatTy > > >
389
- {
397
+ fn unification_table < ' v > ( infcx : & ' v InferCtxt ) -> & ' v RefCell < UnificationTable < ty:: FloatVid > > {
390
398
return & infcx. float_unification_table ;
391
399
}
392
400
@@ -395,7 +403,7 @@ impl<'tcx> UnifyKey<'tcx, Option<ast::FloatTy>> for ty::FloatVid {
395
403
}
396
404
}
397
405
398
- impl < ' tcx > UnifyValue < ' tcx > for Option < ast:: FloatTy > {
406
+ impl UnifyValue for Option < ast:: FloatTy > {
399
407
}
400
408
401
409
impl < ' tcx > SimplyUnifiable < ' tcx > for ast:: FloatTy {
@@ -407,12 +415,3 @@ impl<'tcx> SimplyUnifiable<'tcx> for ast::FloatTy {
407
415
ty:: terr_float_mismatch ( err)
408
416
}
409
417
}
410
-
411
- impl < ' tcx , K : Repr < ' tcx > , V : Repr < ' tcx > > Repr < ' tcx > for VarValue < K , V > {
412
- fn repr ( & self , tcx : & ty:: ctxt < ' tcx > ) -> String {
413
- match * self {
414
- Redirect ( ref k) => format ! ( "Redirect({})" , k. repr( tcx) ) ,
415
- Root ( ref v, r) => format ! ( "Root({}, {})" , v. repr( tcx) , r)
416
- }
417
- }
418
- }
0 commit comments