@@ -47,14 +47,14 @@ fn new_infer_ctxt(tcx: ty::ctxt) -> infer_ctxt {
47
47
48
48
fn mk_subty ( cx : infer_ctxt , a : ty:: t , b : ty:: t ) -> ures {
49
49
#debug[ ">> mk_subty(%s <: %s)" , cx. ty_to_str ( a) , cx. ty_to_str ( b) ] ;
50
- cx. commit ( cx . vb ) { ||
50
+ cx. commit { ||
51
51
cx. tys ( a, b)
52
52
}
53
53
}
54
54
55
55
fn mk_eqty ( cx : infer_ctxt , a : ty:: t , b : ty:: t ) -> ures {
56
56
#debug[ "> mk_eqty(%s <: %s)" , cx. ty_to_str ( a) , cx. ty_to_str ( b) ] ;
57
- cx. commit ( cx . vb ) { ||
57
+ cx. commit { ||
58
58
mk_subty ( cx, a, b) . then { ||
59
59
mk_subty ( cx, b, a)
60
60
}
@@ -64,7 +64,7 @@ fn mk_eqty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
64
64
fn compare_tys ( tcx : ty:: ctxt , a : ty:: t , b : ty:: t ) -> ures {
65
65
let infcx = new_infer_ctxt ( tcx) ;
66
66
#debug[ "> compare_tys(%s == %s)" , infcx. ty_to_str ( a) , infcx. ty_to_str ( b) ] ;
67
- infcx. commit ( infcx . vb ) { ||
67
+ infcx. commit { ||
68
68
mk_subty ( infcx, a, b) . then { ||
69
69
mk_subty ( infcx, b, a)
70
70
}
@@ -158,30 +158,47 @@ impl unify_methods for infer_ctxt {
158
158
}
159
159
}
160
160
161
- fn commit < T : copy , E : copy , U : copy > ( vb : vals_and_bindings < U > ,
162
- f : fn ( ) -> result < T , E > ) -> result < T , E > {
161
+ fn commit < T : copy , E : copy > ( f : fn ( ) -> result < T , E > ) -> result < T , E > {
162
+
163
+ assert self. vb . bindings . len ( ) == 0 u;
164
+ assert self. rb . bindings . len ( ) == 0 u;
165
+
166
+ let r = self . try ( f) ;
167
+
168
+ // TODO---could use a vec::clear() that ran destructors but kept
169
+ // the vec at its currently allocated length
170
+ self . vb . bindings = [ ] ;
171
+ self . rb . bindings = [ ] ;
163
172
164
- assert vb. bindings . len ( ) == 0 u;
165
- let r = self . try ( vb, f) ;
166
- vec:: clear ( vb. bindings ) ;
167
173
ret r;
168
174
}
169
175
170
- fn try < T : copy , E : copy , U : copy > ( vb : vals_and_bindings < U > ,
171
- f : fn ( ) -> result < T , E > ) -> result < T , E > {
176
+ fn try < T : copy , E : copy > ( f : fn ( ) -> result < T , E > ) -> result < T , E > {
172
177
173
- let l = vb. bindings . len ( ) ;
174
- #debug[ "try(l=%u)" , l] ;
178
+ fn rollback_to < T : copy > ( vb : vals_and_bindings < T > , len : uint ) {
179
+ while vb. bindings . len ( ) != len {
180
+ let ( vid, old_v) = vec:: pop ( vb. bindings ) ;
181
+ vb. vals . insert ( vid, old_v) ;
182
+ }
183
+ }
184
+
185
+ let vbl = self . vb . bindings . len ( ) ;
186
+ let rbl = self . rb . bindings . len ( ) ;
187
+ #debug[ "try(vbl=%u, rbl=%u)" , vbl, rbl] ;
175
188
let r = f ( ) ;
176
189
alt r {
177
190
result : : ok ( _) { #debug[ "try--ok" ] ; }
178
- result:: err ( _) { #debug[ "try--rollback" ] ; }
191
+ result:: err ( _) {
192
+ #debug[ "try--rollback" ] ;
193
+ rollback_to ( self . vb , vbl) ;
194
+ rollback_to ( self . rb , rbl) ;
195
+ }
179
196
}
180
197
ret r;
181
198
}
182
199
183
200
fn get < T : copy > ( vb : vals_and_bindings < T > , vid : uint )
184
- -> { root : uint , bounds : bounds < T > } {
201
+ -> { root : uint , bounds : bounds < T > } {
185
202
186
203
alt vb. vals . find ( vid) {
187
204
none {
@@ -228,7 +245,7 @@ impl unify_methods for infer_ctxt {
228
245
ok ( { lb: b, ub: b} )
229
246
}
230
247
( some ( t_a) , some ( t_b) ) {
231
- let r1 = self . try ( self . vb ) { ||
248
+ let r1 = self . try { ||
232
249
self . tys ( t_a, t_b) . then { ||
233
250
ok ( { lb: a, ub: b} )
234
251
}
@@ -294,8 +311,8 @@ impl unify_methods for infer_ctxt {
294
311
let { root: b_id , bounds : b_bounds } = self . get ( self . vb , b_id) ;
295
312
296
313
#debug[ "vars(<T%u>=%s <: <T%u>=%s)" ,
297
- a_id, self . bounds_to_str ( a_bounds) ,
298
- b_id, self . bounds_to_str ( b_bounds) ] ;
314
+ a_id, self . ty_bounds_to_str ( a_bounds) ,
315
+ b_id, self . ty_bounds_to_str ( b_bounds) ] ;
299
316
300
317
if a_id == b_id { ret self . uok ( ) ; }
301
318
0 commit comments