@@ -1550,26 +1550,36 @@ mod unify {
1550
1550
1551
1551
type var_bindings =
1552
1552
{ sets : ufind:: ufind , types : smallintmap:: smallintmap < t > } ;
1553
+ type region_bindings =
1554
+ { sets : ufind:: ufind , regions : smallintmap:: smallintmap < region > } ;
1553
1555
1554
1556
enum unify_style {
1555
1557
precise,
1556
1558
in_bindings( @var_bindings ) ,
1559
+ in_region_bindings( @var_bindings , @region_bindings )
1557
1560
}
1558
1561
type uctxt = { st : unify_style , tcx : ctxt } ;
1559
1562
1560
1563
fn mk_var_bindings ( ) -> @var_bindings {
1561
1564
ret @{ sets : ufind:: make ( ) , types : smallintmap:: mk :: < t > ( ) } ;
1562
1565
}
1563
1566
1567
+ fn mk_region_bindings ( ) -> @region_bindings {
1568
+ ret @{ sets : ufind:: make ( ) , regions : smallintmap:: mk :: < region > ( ) } ;
1569
+ }
1570
+
1564
1571
// Unifies two sets.
1565
1572
fn union < T : copy > (
1566
1573
cx : @uctxt , set_a : uint , set_b : uint ,
1567
1574
variance : variance , nxt : fn ( ) -> ures < T > ) -> ures < T > {
1568
1575
1569
1576
let vb = alt cx. st {
1577
+ in_region_bindings ( vb, _) { vb }
1570
1578
in_bindings ( vb) { vb }
1571
- _ { cx. tcx . sess . bug ( "someone forgot to document an invariant \
1572
- in union") ; }
1579
+ precise {
1580
+ cx. tcx . sess . bug ( "someone forgot to document an invariant \
1581
+ in union") ;
1582
+ }
1573
1583
} ;
1574
1584
ufind:: grow ( vb. sets , uint:: max ( set_a, set_b) + 1 u) ;
1575
1585
let root_a = ufind:: find ( vb. sets , set_a) ;
@@ -1604,6 +1614,54 @@ mod unify {
1604
1614
}
1605
1615
}
1606
1616
1617
+ // Unifies two region sets.
1618
+ //
1619
+ // FIXME: This is a straight copy of the code above. We should use
1620
+ // polymorphism to make this better.
1621
+ fn union_region_sets < T : copy > (
1622
+ cx : @uctxt , set_a : uint , set_b : uint ,
1623
+ variance : variance , nxt : fn ( ) -> ures < T > ) -> ures < T > {
1624
+
1625
+ let rb = alt cx. st {
1626
+ in_region_bindings ( _, rb) { rb }
1627
+ in_bindings ( _) | precise {
1628
+ cx. tcx . sess . bug ( "attempted to unify two region sets without \
1629
+ a set of region bindings present") ;
1630
+ }
1631
+ } ;
1632
+ ufind:: grow ( rb. sets , uint:: max ( set_a, set_b) + 1 u) ;
1633
+ let root_a = ufind:: find ( rb. sets , set_a) ;
1634
+ let root_b = ufind:: find ( rb. sets , set_b) ;
1635
+
1636
+ let replace_region = (
1637
+ fn @( rb: @region_bindings, r: region) {
1638
+ ufind:: union ( rb. sets , set_a, set_b) ;
1639
+ let root_c: uint = ufind:: find ( rb. sets , set_a) ;
1640
+ smallintmap:: insert :: < region > ( rb. regions , root_c, r) ;
1641
+ }
1642
+ ) ;
1643
+
1644
+ alt smallintmap:: find ( rb. regions , root_a) {
1645
+ none {
1646
+ alt smallintmap:: find ( rb. regions , root_b) {
1647
+ none { ufind : : union ( rb. sets , set_a, set_b) ; ret nxt ( ) ; }
1648
+ some ( r_b) { replace_region ( rb, r_b) ; ret nxt( ) ; }
1649
+ }
1650
+ }
1651
+ some ( r_a) {
1652
+ alt smallintmap:: find ( rb. regions , root_b) {
1653
+ none { replace_region( rb, r_a) ; ret nxt( ) ; }
1654
+ some ( r_b) {
1655
+ ret unify_regions ( cx, r_a, r_b, variance) { |r_c|
1656
+ replace_region ( rb, r_c) ;
1657
+ nxt ( )
1658
+ } ;
1659
+ }
1660
+ }
1661
+ }
1662
+ }
1663
+ }
1664
+
1607
1665
fn record_var_binding < T : copy > (
1608
1666
cx : @uctxt , key : int ,
1609
1667
typ : t , variance : variance ,
0 commit comments