Skip to content

Commit 3e47442

Browse files
committed
rustc: Add region unification functions
1 parent 68e364b commit 3e47442

File tree

1 file changed

+60
-2
lines changed

1 file changed

+60
-2
lines changed

src/rustc/middle/ty.rs

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,26 +1550,36 @@ mod unify {
15501550

15511551
type var_bindings =
15521552
{sets: ufind::ufind, types: smallintmap::smallintmap<t>};
1553+
type region_bindings =
1554+
{sets: ufind::ufind, regions: smallintmap::smallintmap<region>};
15531555

15541556
enum unify_style {
15551557
precise,
15561558
in_bindings(@var_bindings),
1559+
in_region_bindings(@var_bindings, @region_bindings)
15571560
}
15581561
type uctxt = {st: unify_style, tcx: ctxt};
15591562

15601563
fn mk_var_bindings() -> @var_bindings {
15611564
ret @{sets: ufind::make(), types: smallintmap::mk::<t>()};
15621565
}
15631566

1567+
fn mk_region_bindings() -> @region_bindings {
1568+
ret @{sets: ufind::make(), regions: smallintmap::mk::<region>()};
1569+
}
1570+
15641571
// Unifies two sets.
15651572
fn union<T:copy>(
15661573
cx: @uctxt, set_a: uint, set_b: uint,
15671574
variance: variance, nxt: fn() -> ures<T>) -> ures<T> {
15681575

15691576
let vb = alt cx.st {
1577+
in_region_bindings(vb, _) { vb }
15701578
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+
}
15731583
};
15741584
ufind::grow(vb.sets, uint::max(set_a, set_b) + 1u);
15751585
let root_a = ufind::find(vb.sets, set_a);
@@ -1604,6 +1614,54 @@ mod unify {
16041614
}
16051615
}
16061616

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) + 1u);
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+
16071665
fn record_var_binding<T:copy>(
16081666
cx: @uctxt, key: int,
16091667
typ: t, variance: variance,

0 commit comments

Comments
 (0)