@@ -9,6 +9,7 @@ import util::ppaux::{ty_to_str, mt_to_str};
9
9
import result:: { result, extensions, ok, err, map, map2, iter2} ;
10
10
import ty:: type_is_bot;
11
11
import driver:: session:: session;
12
+ import util:: common:: { indent, indenter} ;
12
13
13
14
export infer_ctxt;
14
15
export new_infer_ctxt;
@@ -66,25 +67,31 @@ fn new_infer_ctxt(tcx: ty::ctxt) -> infer_ctxt {
66
67
}
67
68
68
69
fn mk_subty ( cx : infer_ctxt , a : ty:: t , b : ty:: t ) -> ures {
69
- #debug[ ">> mk_subty(%s <: %s)" , a. to_str ( cx) , b. to_str ( cx) ] ;
70
- cx. commit { ||
71
- cx. tys ( a, b)
70
+ #debug[ "mk_subty(%s <: %s)" , a. to_str ( cx) , b. to_str ( cx) ] ;
71
+ indent { ||
72
+ cx. commit { ||
73
+ cx. tys ( a, b)
74
+ }
72
75
}
73
76
}
74
77
75
78
fn mk_eqty ( cx : infer_ctxt , a : ty:: t , b : ty:: t ) -> ures {
76
- #debug[ ">> mk_eqty(%s <: %s)" , a. to_str ( cx) , b. to_str ( cx) ] ;
77
- cx. commit { ||
78
- cx. eq_tys ( a, b)
79
+ #debug[ "mk_eqty(%s <: %s)" , a. to_str ( cx) , b. to_str ( cx) ] ;
80
+ indent { ||
81
+ cx. commit { ||
82
+ cx. eq_tys ( a, b)
83
+ }
79
84
}
80
85
}
81
86
82
87
fn compare_tys ( tcx : ty:: ctxt , a : ty:: t , b : ty:: t ) -> ures {
83
88
let infcx = new_infer_ctxt ( tcx) ;
84
- #debug[ ">> compare_tys(%s == %s)" , a. to_str ( infcx) , b. to_str ( infcx) ] ;
85
- infcx. commit { ||
86
- mk_subty ( infcx, a, b) . then { ||
87
- mk_subty ( infcx, b, a)
89
+ #debug[ "compare_tys(%s == %s)" , a. to_str ( infcx) , b. to_str ( infcx) ] ;
90
+ indent { ||
91
+ infcx. commit { ||
92
+ mk_subty ( infcx, a, b) . then { ||
93
+ mk_subty ( infcx, b, a)
94
+ }
88
95
}
89
96
}
90
97
}
@@ -226,24 +233,22 @@ impl unify_methods for infer_ctxt {
226
233
self . set ( self . vb , vid, new_v) ;
227
234
}
228
235
229
- fn commit < T : copy , E : copy > ( f : fn ( ) -> result < T , E > ) -> result < T , E > {
236
+ fn commit < T , E > ( f : fn ( ) -> result < T , E > ) -> result < T , E > {
230
237
231
238
assert self. vb . bindings . len ( ) == 0 u;
232
239
assert self. rb . bindings . len ( ) == 0 u;
233
240
234
- let r = self . try ( f) ;
241
+ let r <- self . try( f ) ;
235
242
236
243
// TODO---could use a vec::clear() that ran destructors but kept
237
244
// the vec at its currently allocated length
238
245
self . vb . bindings = [ ] ;
239
246
self . rb . bindings = [ ] ;
240
247
241
- #debug[ ">> Commit result: %?" , r] ;
242
-
243
248
ret r;
244
249
}
245
250
246
- fn try < T : copy , E : copy > ( f : fn ( ) -> result < T , E > ) -> result < T , E > {
251
+ fn try < T , E > ( f : fn ( ) -> result < T , E > ) -> result < T , E > {
247
252
248
253
fn rollback_to < V : copy vid, T : copy > (
249
254
vb : vals_and_bindings < V , T > , len : uint ) {
@@ -257,7 +262,7 @@ impl unify_methods for infer_ctxt {
257
262
let vbl = self . vb . bindings . len ( ) ;
258
263
let rbl = self . rb . bindings . len ( ) ;
259
264
#debug[ "try(vbl=%u, rbl=%u)" , vbl, rbl] ;
260
- let r = f ( ) ;
265
+ let r < - f ( ) ;
261
266
alt r {
262
267
result:: ok ( _) { #debug[ "try--ok" ] ; }
263
268
result:: err ( _) {
@@ -309,6 +314,9 @@ impl unify_methods for infer_ctxt {
309
314
a : bound < V > , b : bound < V > ,
310
315
merge_op : fn ( V , V ) -> cres < V > ) -> cres < bound < V > > {
311
316
317
+ #debug[ "merge_bnd(%s,%s)" , a. to_str ( self ) , b. to_str ( self ) ] ;
318
+ let _r = indenter ( ) ;
319
+
312
320
alt ( a, b) {
313
321
( none, none) {
314
322
ok ( none)
@@ -332,6 +340,7 @@ impl unify_methods for infer_ctxt {
332
340
lub : fn ( V , V ) -> cres < V > ,
333
341
glb : fn ( V , V ) -> cres < V > ) -> cres < bounds < V > > {
334
342
343
+ let _r = indenter ( ) ;
335
344
self . merge_bnd ( a. ub , b. ub , glb) . chain { |ub|
336
345
#debug[ "glb of ubs %s and %s is %s" ,
337
346
a. ub . to_str ( self ) , b. ub . to_str ( self ) ,
@@ -383,6 +392,7 @@ impl unify_methods for infer_ctxt {
383
392
// them explicitly gives the type inferencer more
384
393
// information and helps to produce tighter bounds
385
394
// when necessary.
395
+ indent { ||
386
396
self . bnds ( a. lb , b. ub ) . then { ||
387
397
self . bnds ( b. lb , a. ub ) . then { ||
388
398
self . merge_bnd ( a. ub , b. ub , { |x, y| x. glb ( self , y) } ) . chain { |ub|
@@ -395,10 +405,10 @@ impl unify_methods for infer_ctxt {
395
405
// the new bounds must themselves
396
406
// be relatable:
397
407
self . bnds ( bnds. lb , bnds. ub ) . then { ||
398
- self . set( vb, v_id, bounded( bnds) ) ;
399
- self . uok( )
408
+ self . set ( vb, v_id, bounded ( bnds) ) ;
409
+ self . uok ( )
400
410
}
401
- } } } }
411
+ } } } } }
402
412
}
403
413
404
414
fn vars<V : copy vid, T : copy to_str st> (
@@ -465,46 +475,29 @@ impl unify_methods for infer_ctxt {
465
475
}
466
476
467
477
fn regions ( a : ty:: region , b : ty:: region ) -> ures {
468
- alt ( a, b) { // XXX
469
- ( ty:: re_var( a_id) , ty:: re_var( b_id) ) {
470
- self . vars( self . rb, a_id, b_id)
471
- }
472
- ( ty:: re_var( a_id) , _) {
473
- self . vart( self . rb, a_id, b)
474
- }
475
- ( _, ty:: re_var( b_id) ) {
476
- self . tvar( self . rb, a, b_id)
477
- }
478
-
479
- ( ty:: re_free( a_id, _) , ty:: re_scope( b_id) ) |
480
- ( ty:: re_scope( a_id) , ty:: re_free( b_id, _) ) |
481
- ( ty:: re_scope( a_id) , ty:: re_scope( b_id) ) {
482
- let rm = self . tcx. region_map;
483
- alt region:: nearest_common_ancestor( rm, a_id, b_id) {
484
- some( r_id) if r_id == a_id { self . uok( ) }
485
- _ { err( ty:: terr_regions_differ( false , b, a) ) }
486
- }
487
- }
478
+ #debug[ "regions(%s <= %s)" , a. to_str ( self ) , b. to_str ( self ) ] ;
479
+ indent { ||
480
+ alt ( a, b) {
481
+ ( ty:: re_var ( a_id) , ty:: re_var ( b_id) ) {
482
+ self . vars ( self . rb , a_id, b_id)
483
+ }
484
+ ( ty:: re_var ( a_id) , _) {
485
+ self . vart ( self . rb , a_id, b)
486
+ }
487
+ ( _, ty:: re_var ( b_id) ) {
488
+ self . tvar ( self . rb , a, b_id)
489
+ }
488
490
489
- // For these types, we cannot define any additional relationship:
490
- ( ty:: re_free( _, _) , ty:: re_free( _, _) ) |
491
- ( ty:: re_bound( _) , ty:: re_bound( _) ) |
492
- ( ty:: re_bound( _) , ty:: re_free( _, _) ) |
493
- ( ty:: re_bound( _) , ty:: re_scope( _) ) |
494
- ( ty:: re_free( _, _) , ty:: re_bound( _) ) |
495
- ( ty:: re_scope( _) , ty:: re_bound( _) ) {
496
- if a == b {
497
- self . uok( )
498
- } else {
499
- err( ty:: terr_regions_differ( false , b, a) )
491
+ _ {
492
+ lub( self ) . c_regions ( a, b) . chain { |r|
493
+ if b == r {
494
+ self . uok ( )
495
+ } else {
496
+ err ( ty:: terr_regions_differ ( false , b, a) )
497
+ }
498
+ }
499
+ }
500
500
}
501
- }
502
-
503
- ( ty:: re_default, _) |
504
- ( _, ty:: re_default) {
505
- // actually a compiler bug, I think.
506
- err( ty:: terr_regions_differ( false , b, a) )
507
- }
508
501
}
509
502
}
510
503
@@ -657,16 +650,17 @@ impl unify_methods for infer_ctxt {
657
650
a : bound < T > , b : bound < T > ) -> ures {
658
651
659
652
#debug ( "bnds(%s <: %s)" , a. to_str ( self ) , b. to_str ( self ) ) ;
660
-
661
- alt ( a, b) {
662
- ( none, none) |
663
- ( some( _) , none) |
664
- ( none, some( _) ) {
665
- self . uok( )
666
- }
667
- ( some( t_a) , some( t_b) ) {
668
- t_a. st( self , t_b)
669
- }
653
+ indent { ||
654
+ alt ( a, b) {
655
+ ( none, none) |
656
+ ( some ( _) , none) |
657
+ ( none, some ( _) ) {
658
+ self . uok ( )
659
+ }
660
+ ( some ( t_a) , some ( t_b) ) {
661
+ t_a. st ( self , t_b)
662
+ }
663
+ }
670
664
}
671
665
}
672
666
@@ -744,7 +738,9 @@ impl unify_methods for infer_ctxt {
744
738
745
739
( ty:: ty_rptr ( a_r, a_mt) , ty:: ty_rptr ( b_r, b_mt) ) {
746
740
self . mts ( a_mt, b_mt) . then { ||
747
- self . regions( a_r, b_r)
741
+ // Non-obvious: for &a.T to be a subtype of &b.T, &a
742
+ // must exist for LONGER than &b. That is, &b <= &a.
743
+ self . regions ( b_r, a_r)
748
744
}
749
745
}
750
746
@@ -972,8 +968,11 @@ iface combine {
972
968
973
969
// Combining regions (along with some specific cases that are
974
970
// different for LUB/GLB):
971
+ fn c_contraregions (
972
+ a : ty:: region , b : ty:: region ) -> cres < ty:: region > ;
975
973
fn c_regions (
976
974
a : ty:: region , b : ty:: region ) -> cres < ty:: region > ;
975
+ fn c_regions_static ( r : ty:: region ) -> cres < ty:: region > ;
977
976
fn c_regions_scope_scope (
978
977
a : ty:: region , a_id : ast:: node_id ,
979
978
b : ty:: region , b_id : ast:: node_id ) -> cres < ty:: region > ;
@@ -1045,11 +1044,13 @@ fn c_var_t<V:copy vid, C:combine, T:copy to_str st>(
1045
1044
alt self. bnd ( a_bounds) {
1046
1045
some ( a_bnd) {
1047
1046
// If a has an upper bound, return it.
1047
+ #debug[ "bnd=some(%s)" , a_bnd. to_str ( self . infcx ( ) ) ] ;
1048
1048
ret c_ts ( a_bnd, b) ;
1049
1049
}
1050
1050
none {
1051
1051
// If a does not have an upper bound, make b the upper bound of a
1052
1052
// and then return b.
1053
+ #debug[ "bnd=none"] ;
1053
1054
let a_bounds = self . with_bnd ( a_bounds, b) ;
1054
1055
self . infcx ( ) . bnds ( a_bounds. lb , a_bounds. ub ) . then { ||
1055
1056
self . infcx ( ) . set ( vb, a_id, bounded ( a_bounds) ) ;
@@ -1162,6 +1163,7 @@ fn c_tys<C:combine>(
1162
1163
// Fast path.
1163
1164
if a == b { ret ok( a) ; }
1164
1165
1166
+ indent { ||
1165
1167
alt ( ty:: get ( a) . struct , ty:: get ( b) . struct ) {
1166
1168
( ty:: ty_bot, _) { self . c_bot ( b) }
1167
1169
( _, ty:: ty_bot) { self . c_bot ( b) }
@@ -1249,7 +1251,7 @@ fn c_tys<C:combine>(
1249
1251
}
1250
1252
1251
1253
( ty:: ty_rptr ( a_r, a_mt) , ty:: ty_rptr ( b_r, b_mt) ) {
1252
- self . c_regions ( a_r, b_r) . chain { |r|
1254
+ self . c_contraregions ( a_r, b_r) . chain { |r|
1253
1255
self . c_mts ( a_mt, b_mt) . chain { |mt|
1254
1256
ok ( ty:: mk_rptr ( tcx, r, mt) )
1255
1257
}
@@ -1293,6 +1295,7 @@ fn c_tys<C:combine>(
1293
1295
1294
1296
_ { err ( ty:: terr_mismatch) }
1295
1297
}
1298
+ }
1296
1299
}
1297
1300
1298
1301
fn c_regions < C : combine > (
@@ -1303,7 +1306,12 @@ fn c_regions<C:combine>(
1303
1306
a. to_str ( self . infcx ( ) ) ,
1304
1307
b. to_str ( self . infcx ( ) ) ] ;
1305
1308
1309
+ indent { ||
1306
1310
alt ( a, b) {
1311
+ ( ty:: re_static, r) | ( r, ty:: re_static) {
1312
+ self . c_regions_static ( r)
1313
+ }
1314
+
1307
1315
( ty:: re_var ( a_id) , ty:: re_var ( b_id) ) {
1308
1316
c_vars ( self , self . infcx ( ) . rb ,
1309
1317
a, a_id, b_id,
@@ -1352,6 +1360,7 @@ fn c_regions<C:combine>(
1352
1360
err ( ty:: terr_regions_differ ( false , b, a) )
1353
1361
}
1354
1362
}
1363
+ }
1355
1364
}
1356
1365
1357
1366
impl of combine for lub {
@@ -1443,6 +1452,16 @@ impl of combine for lub {
1443
1452
ret c_regions ( self , a, b) ;
1444
1453
}
1445
1454
1455
+ fn c_contraregions ( a : ty:: region , b : ty:: region ) -> cres < ty:: region > {
1456
+ ret glb ( self . infcx ( ) ) . c_regions ( a, b) ;
1457
+ }
1458
+
1459
+ fn c_regions_static ( _r : ty:: region ) -> cres < ty:: region > {
1460
+ // LUB of `r` and static is always static---what's bigger than
1461
+ // that?
1462
+ ret ok( ty:: re_static) ;
1463
+ }
1464
+
1446
1465
fn c_regions_free_scope (
1447
1466
a : ty:: region , _a_id : ast:: node_id , _a_br : ty:: bound_region ,
1448
1467
_b : ty:: region , _b_id : ast:: node_id ) -> cres < ty:: region > {
@@ -1573,6 +1592,16 @@ impl of combine for glb {
1573
1592
ret c_regions ( self , a, b) ;
1574
1593
}
1575
1594
1595
+ fn c_contraregions ( a : ty:: region , b : ty:: region ) -> cres < ty:: region > {
1596
+ ret lub ( self . infcx ( ) ) . c_regions ( a, b) ;
1597
+ }
1598
+
1599
+ fn c_regions_static ( r : ty:: region ) -> cres < ty:: region > {
1600
+ // GLB of `r` and static is always `r`; static is bigger than
1601
+ // everything
1602
+ ret ok( r) ;
1603
+ }
1604
+
1576
1605
fn c_regions_free_scope (
1577
1606
_a : ty:: region , _a_id : ast:: node_id , _a_br : ty:: bound_region ,
1578
1607
b : ty:: region , _b_id : ast:: node_id ) -> cres < ty:: region > {
0 commit comments