Skip to content

Commit bd6e6e3

Browse files
committed
rustc: Stub some region resolution stuff in infer
1 parent f507b54 commit bd6e6e3

File tree

1 file changed

+103
-3
lines changed

1 file changed

+103
-3
lines changed

src/rustc/middle/infer.rs

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,21 @@ enum var_value {
2525
bounded(bounds)
2626
}
2727

28+
type region_bound = option<ty::region>;
29+
30+
type region_bounds = {lb: region_bound, ub: region_bound};
31+
32+
enum region_value {
33+
rv_redirect(uint),
34+
rv_bounded(region_bounds)
35+
}
36+
2837
enum infer_ctxt = @{
2938
tcx: ty::ctxt,
3039
vals: smallintmap<var_value>,
31-
mut bindings: [(uint, var_value)]
40+
mut bindings: [(uint, var_value)],
41+
region_vals: smallintmap<region_value>,
42+
mut region_bindings: [(uint, region_value)]
3243
};
3344

3445
type ures = result::result<(), ty::type_err>;
@@ -37,7 +48,9 @@ type fres<T> = result::result<T,int>;
3748
fn new_infer_ctxt(tcx: ty::ctxt) -> infer_ctxt {
3849
infer_ctxt(@{tcx: tcx,
3950
vals: smallintmap::mk(),
40-
mut bindings: []})
51+
mut bindings: [],
52+
region_vals: smallintmap::mk(),
53+
mut region_bindings: []})
4154
}
4255

4356
fn mk_subty(cx: infer_ctxt, a: ty::t, b: ty::t) -> ures {
@@ -186,6 +199,28 @@ impl unify_methods for infer_ctxt {
186199
}
187200
}
188201

202+
// FIXME: See if we can't throw some polymorphism on this to make this
203+
// less of a straight copy of the above.
204+
fn get_region(rid: uint) -> {root: uint, bounds:region_bounds} {
205+
alt self.region_vals.find(rid) {
206+
none {
207+
let bnds = {lb: none, ub: none};
208+
self.region_vals.insert(rid, rv_bounded(bnds));
209+
{root: rid, bounds: bnds}
210+
}
211+
some(rv_redirect(rid)) {
212+
let {root, bounds} = self.get_region(rid);
213+
if root != rid {
214+
self.region_vals.insert(rid, rv_redirect(root));
215+
}
216+
{root: root, bounds: bounds}
217+
}
218+
some(rv_bounded(bounds)) {
219+
{root: rid, bounds: bounds}
220+
}
221+
}
222+
}
223+
189224
// Combines the two bounds. Returns a bounds r where (r.lb <:
190225
// a,b) and (a,b <: r.ub) (if such a bounds exists).
191226
fn merge_bnds(a: bound, b: bound) -> result<bounds, ty::type_err> {
@@ -603,7 +638,7 @@ impl resolve_methods for infer_ctxt {
603638
result::ok(t)
604639
}
605640

606-
fn rerr(v: int) -> fres<ty::t> {
641+
fn rerr<T>(v: int) -> fres<T> {
607642
#debug["Resolve error: %?", v];
608643
result::err(v)
609644
}
@@ -628,6 +663,14 @@ impl resolve_methods for infer_ctxt {
628663
fn resolve_ty(typ: ty::t) -> fres<ty::t> {
629664
alt ty::get(typ).struct {
630665
ty::ty_var(vid) { self.resolve_var(vid) }
666+
ty::ty_rptr(ty::re_var(rid), base_ty) {
667+
alt self.resolve_region(rid as int) {
668+
result::err(terr) { result::err(terr) }
669+
result::ok(region) {
670+
self.rok(ty::mk_rptr(self.tcx, region, base_ty))
671+
}
672+
}
673+
}
631674
_ { self.rok(typ) }
632675
}
633676
}
@@ -682,4 +725,61 @@ impl resolve_methods for infer_ctxt {
682725
some(var_id) { ret self.rerr(var_id); }
683726
}
684727
}
728+
729+
// FIXME: These should be integrated with the two functions above instead
730+
// of being such blatant lazy duplicates.
731+
732+
fn resolve_region(rid: int) -> fres<ty::region> {
733+
let {root:_, bounds} = self.get_region(rid as uint);
734+
735+
// See comments in resolve_ty above re. nonobviousness.
736+
737+
alt bounds {
738+
{ ub:_, lb:some(r) } |
739+
{ ub:some(r), lb:_ } |
740+
{ ub:_, lb:some(r) } { result::ok(r) }
741+
{ ub:none, lb:none } { self.rerr(rid) }
742+
}
743+
}
744+
745+
fn subst_regions(unresolved: @mutable option<int>,
746+
regions_seen: std::list::list<int>,
747+
rid: int) -> ty::region {
748+
// Should really return a fixup_result instead of a t, but fold_ty
749+
// doesn't allow returning anything but a t.
750+
alt self.resolve_region(rid) {
751+
result::err(rid) {
752+
*unresolved = some(rid);
753+
ret ty::re_var(rid as uint);
754+
}
755+
result::ok(rr) {
756+
let mut give_up = false;
757+
std::list::iter(regions_seen) {|r|
758+
if r == rid {
759+
*unresolved = some(-1); // hack: communicate inf region
760+
give_up = true;
761+
}
762+
}
763+
ret rr;
764+
}
765+
}
766+
}
767+
768+
fn fixup_regions(typ: ty::t) -> fres<ty::t> {
769+
let unresolved = @mutable none::<int>;
770+
let rty = ty::fold_ty(self.tcx, ty::fm_rptr({ |region, _under_rptr|
771+
alt region {
772+
ty::re_var(rid) {
773+
self.subst_regions(unresolved, std::list::nil, rid as int)
774+
}
775+
_ { region }
776+
}
777+
}), typ);
778+
779+
let ur = *unresolved;
780+
alt ur {
781+
none { ret self.rok(rty); }
782+
some(var_id) { ret self.rerr(var_id); }
783+
}
784+
}
685785
}

0 commit comments

Comments
 (0)