From 906169d608c51b032666e05fff4d870968abe9d4 Mon Sep 17 00:00:00 2001 From: Lindsey Kuper Date: Mon, 18 Jun 2012 16:41:42 -0700 Subject: [PATCH] Add a `node` type in place of hand-rolled records in infer --- src/rustc/middle/typeck/infer.rs | 93 ++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 27 deletions(-) diff --git a/src/rustc/middle/typeck/infer.rs b/src/rustc/middle/typeck/infer.rs index 33c1728ff115..8d4571ecc9cc 100644 --- a/src/rustc/middle/typeck/infer.rs +++ b/src/rustc/middle/typeck/infer.rs @@ -275,6 +275,11 @@ type vals_and_bindings = { mut bindings: [(V, var_value)] }; +enum node = { + root: V, + possible_types: T, +}; + enum infer_ctxt = @{ tcx: ty::ctxt, @@ -639,7 +644,7 @@ impl unify_methods for infer_ctxt { fn get( vb: vals_and_bindings, vid: V) - -> {root: V, possible_types: T} { + -> node { alt vb.vals.find(vid.to_uint()) { none { @@ -649,15 +654,15 @@ impl unify_methods for infer_ctxt { some(var_val) { alt var_val { redirect(vid) { - let {root: rt, possible_types: pt} = self.get(vb, vid); - if rt != vid { + let nde = self.get(vb, vid); + if nde.root != vid { // Path compression - vb.vals.insert(vid.to_uint(), redirect(rt)); + vb.vals.insert(vid.to_uint(), redirect(nde.root)); } - {root: rt, possible_types: pt} + nde } root(pt) { - {root: vid, possible_types: pt} + node({root: vid, possible_types: pt}) } } } @@ -771,8 +776,12 @@ impl unify_methods for infer_ctxt { a_id: V, b_id: V) -> ures { // Need to make sub_id a subtype of sup_id. - let {root: a_id, possible_types: a_bounds} = self.get(vb, a_id); - let {root: b_id, possible_types: b_bounds} = self.get(vb, b_id); + let nde_a = self.get(vb, a_id); + let nde_b = self.get(vb, b_id); + let a_id = nde_a.root; + let b_id = nde_b.root; + let a_bounds = nde_a.possible_types; + let b_bounds = nde_b.possible_types; #debug["vars(%s=%s <: %s=%s)", a_id.to_str(), a_bounds.to_str(self), @@ -809,8 +818,12 @@ impl unify_methods for infer_ctxt { vb: vals_and_bindings, a_id: V, b_id: V) -> ures { - let {root: a_id, possible_types: a_pt} = self.get(vb, a_id); - let {root: b_id, possible_types: b_pt} = self.get(vb, b_id); + let nde_a = self.get(vb, a_id); + let nde_b = self.get(vb, b_id); + let a_id = nde_a.root; + let b_id = nde_b.root; + let a_pt = nde_a.possible_types; + let b_pt = nde_b.possible_types; // If we're already dealing with the same two variables, // there's nothing to do. @@ -831,7 +844,10 @@ impl unify_methods for infer_ctxt { vb: vals_and_bindings>, a_id: V, b: T) -> ures { - let {root: a_id, possible_types: a_bounds} = self.get(vb, a_id); + let nde_a = self.get(vb, a_id); + let a_id = nde_a.root; + let a_bounds = nde_a.possible_types; + #debug["vart(%s=%s <: %s)", a_id.to_str(), a_bounds.to_str(self), b.to_str(self)]; @@ -845,7 +861,9 @@ impl unify_methods for infer_ctxt { assert ty::type_is_integral(b); - let {root: a_id, possible_types: a_pt} = self.get(vb, a_id); + let nde_a = self.get(vb, a_id); + let a_id = nde_a.root; + let a_pt = nde_a.possible_types; let intersection = intersection(a_pt, convert_integral_ty_to_int_ty_set( @@ -862,7 +880,10 @@ impl unify_methods for infer_ctxt { a: T, b_id: V) -> ures { let a_bounds = {lb: some(a), ub: none}; - let {root: b_id, possible_types: b_bounds} = self.get(vb, b_id); + let nde_b = self.get(vb, b_id); + let b_id = nde_b.root; + let b_bounds = nde_b.possible_types; + #debug["tvar(%s <: %s=%s)", a.to_str(self), b_id.to_str(), b_bounds.to_str(self)]; @@ -875,7 +896,9 @@ impl unify_methods for infer_ctxt { assert ty::type_is_integral(a); - let {root: b_id, possible_types: b_pt} = self.get(vb, b_id); + let nde_b = self.get(vb, b_id); + let b_id = nde_b.root; + let b_pt = nde_b.possible_types; let intersection = intersection(b_pt, convert_integral_ty_to_int_ty_set( @@ -1101,8 +1124,9 @@ impl methods for resolve_state { ret ty::re_var(rid); } else { vec::push(self.r_seen, rid); - let {root:_, possible_types: bounds} = - self.infcx.get(self.infcx.rb, rid); + let nde = self.infcx.get(self.infcx.rb, rid); + let bounds = nde.possible_types; + let r1 = alt bounds { { ub:_, lb:some(t) } { self.resolve_region(t) } { ub:some(t), lb:_ } { self.resolve_region(t) } @@ -1135,8 +1159,9 @@ impl methods for resolve_state { // tend to carry more restrictions or higher // perf. penalties, so it pays to know more. - let {root:_, possible_types: bounds} = - self.infcx.get(self.infcx.tvb, vid); + let nde = self.infcx.get(self.infcx.tvb, vid); + let bounds = nde.possible_types; + let t1 = alt bounds { { ub:_, lb:some(t) } if !type_is_bot(t) { self.resolve1(t) } { ub:some(t), lb:_ } { self.resolve1(t) } @@ -1157,8 +1182,9 @@ impl methods for resolve_state { } fn resolve_ty_var_integral(vid: tvi_vid) -> ty::t { - let {root:_, possible_types: pt} = - self.infcx.get(self.infcx.tvib, vid); + let nde = self.infcx.get(self.infcx.tvib, vid); + let pt = nde.possible_types; + // If there's only one type in the set of possible types, then // that's the answer. alt single_type_contained_in(self.infcx.tcx, pt) { @@ -1258,21 +1284,28 @@ impl assignment for infer_ctxt { } (ty::ty_var(a_id), ty::ty_var(b_id)) { - let {root:_, possible_types: a_bounds} = self.get(self.tvb, a_id); - let {root:_, possible_types: b_bounds} = self.get(self.tvb, b_id); + let nde_a = self.get(self.tvb, a_id); + let nde_b = self.get(self.tvb, b_id); + let a_bounds = nde_a.possible_types; + let b_bounds = nde_b.possible_types; + let a_bnd = select(a_bounds.ub, a_bounds.lb); let b_bnd = select(b_bounds.lb, b_bounds.ub); self.assign_tys_or_sub(anmnt, a, b, a_bnd, b_bnd) } (ty::ty_var(a_id), _) { - let {root:_, possible_types:a_bounds} = self.get(self.tvb, a_id); + let nde_a = self.get(self.tvb, a_id); + let a_bounds = nde_a.possible_types; + let a_bnd = select(a_bounds.ub, a_bounds.lb); self.assign_tys_or_sub(anmnt, a, b, a_bnd, some(b)) } (_, ty::ty_var(b_id)) { - let {root:_, possible_types: b_bounds} = self.get(self.tvb, b_id); + let nde_b = self.get(self.tvb, b_id); + let b_bounds = nde_b.possible_types; + let b_bnd = select(b_bounds.lb, b_bounds.ub); self.assign_tys_or_sub(anmnt, a, b, some(a), b_bnd) } @@ -2466,8 +2499,12 @@ fn lattice_vars( // upper/lower/sub/super/etc. // Need to find a type that is a supertype of both a and b: - let {root: a_vid, possible_types: a_bounds} = self.infcx().get(vb, a_vid); - let {root: b_vid, possible_types: b_bounds} = self.infcx().get(vb, b_vid); + let nde_a = self.infcx().get(vb, a_vid); + let nde_b = self.infcx().get(vb, b_vid); + let a_vid = nde_a.root; + let b_vid = nde_b.root; + let a_bounds = nde_a.possible_types; + let b_bounds = nde_b.possible_types; #debug["%s.lattice_vars(%s=%s <: %s=%s)", self.tag(), @@ -2503,7 +2540,9 @@ fn lattice_var_t( a_id: V, b: T, c_ts: fn(T, T) -> cres) -> cres { - let {root: a_id, possible_types: a_bounds} = self.infcx().get(vb, a_id); + let nde_a = self.infcx().get(vb, a_id); + let a_id = nde_a.root; + let a_bounds = nde_a.possible_types; // The comments in this function are written for LUB, but they // apply equally well to GLB if you inverse upper/lower/sub/super/etc.