Skip to content

Commit

Permalink
Refactor the unification code and rejuvenate the unit test
Browse files Browse the repository at this point in the history
infrastructure that has been accidentally left out of the build
for a rather long time (it was still using `@DVec`!)
  • Loading branch information
nikomatsakis committed Jun 22, 2014
1 parent 4c39962 commit 020373f
Show file tree
Hide file tree
Showing 15 changed files with 1,353 additions and 997 deletions.
42 changes: 14 additions & 28 deletions src/librustc/middle/ty.rs
Expand Up @@ -850,17 +850,23 @@ impl CLike for BuiltinBound {
}

#[deriving(Clone, PartialEq, Eq, Hash)]
pub struct TyVid(pub uint);
pub struct TyVid {
pub index: uint
}

#[deriving(Clone, PartialEq, Eq, Hash)]
pub struct IntVid(pub uint);
pub struct IntVid {
pub index: uint
}

#[deriving(Clone, PartialEq, Eq, Hash)]
pub struct FloatVid(pub uint);
pub struct FloatVid {
pub index: uint
}

#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
pub struct RegionVid {
pub id: uint
pub index: uint
}

#[deriving(Clone, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -893,47 +899,27 @@ impl cmp::PartialEq for InferRegion {
}
}

pub trait Vid {
fn to_uint(&self) -> uint;
}

impl Vid for TyVid {
fn to_uint(&self) -> uint { let TyVid(v) = *self; v }
}

impl fmt::Show for TyVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result{
write!(f, "<generic #{}>", self.to_uint())
write!(f, "<generic #{}>", self.index)
}
}

impl Vid for IntVid {
fn to_uint(&self) -> uint { let IntVid(v) = *self; v }
}

impl fmt::Show for IntVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<generic integer #{}>", self.to_uint())
write!(f, "<generic integer #{}>", self.index)
}
}

impl Vid for FloatVid {
fn to_uint(&self) -> uint { let FloatVid(v) = *self; v }
}

impl fmt::Show for FloatVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<generic float #{}>", self.to_uint())
write!(f, "<generic float #{}>", self.index)
}
}

impl Vid for RegionVid {
fn to_uint(&self) -> uint { self.id }
}

impl fmt::Show for RegionVid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.id.fmt(f)
write!(f, "'<generic lifetime #{}>", self.index)
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/typeck/coherence.rs
Expand Up @@ -519,7 +519,8 @@ impl<'a> CoherenceChecker<'a> {
fn can_unify_universally_quantified<'a>(&self,
a: &'a UniversalQuantificationResult,
b: &'a UniversalQuantificationResult)
-> bool {
-> bool
{
infer::can_mk_subty(&self.inference_context,
a.monotype,
b.monotype).is_ok()
Expand Down
36 changes: 18 additions & 18 deletions src/librustc/middle/typeck/infer/coercion.rs
Expand Up @@ -71,9 +71,9 @@ use middle::ty;
use middle::typeck::infer::{CoerceResult, resolve_type, Coercion};
use middle::typeck::infer::combine::{CombineFields, Combine};
use middle::typeck::infer::sub::Sub;
use middle::typeck::infer::to_str::InferStr;
use middle::typeck::infer::resolve::try_resolve_tvar_shallow;
use util::common::indenter;
use util::ppaux::Repr;

use syntax::abi;
use syntax::ast::MutImmutable;
Expand All @@ -91,8 +91,8 @@ impl<'f> Coerce<'f> {

pub fn tys(&self, a: ty::t, b: ty::t) -> CoerceResult {
debug!("Coerce.tys({} => {})",
a.inf_str(self.get_ref().infcx),
b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx),
b.repr(self.get_ref().infcx.tcx));
let _indent = indenter();

// Examine the supertype and consider auto-borrowing.
Expand Down Expand Up @@ -233,8 +233,8 @@ impl<'f> Coerce<'f> {
mt_b: ty::mt)
-> CoerceResult {
debug!("coerce_borrowed_pointer(a={}, sty_a={:?}, b={}, mt_b={:?})",
a.inf_str(self.get_ref().infcx), sty_a,
b.inf_str(self.get_ref().infcx), mt_b);
a.repr(self.get_ref().infcx.tcx), sty_a,
b.repr(self.get_ref().infcx.tcx), mt_b);

// If we have a parameter of type `&M T_a` and the value
// provided is `expr`, we will be adding an implicit borrow,
Expand Down Expand Up @@ -270,8 +270,8 @@ impl<'f> Coerce<'f> {
b: ty::t)
-> CoerceResult {
debug!("coerce_borrowed_string(a={}, sty_a={:?}, b={})",
a.inf_str(self.get_ref().infcx), sty_a,
b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx), sty_a,
b.repr(self.get_ref().infcx.tcx));

match *sty_a {
ty::ty_uniq(t) => match ty::get(t).sty {
Expand Down Expand Up @@ -300,8 +300,8 @@ impl<'f> Coerce<'f> {
mutbl_b: ast::Mutability)
-> CoerceResult {
debug!("coerce_borrowed_vector(a={}, sty_a={:?}, b={})",
a.inf_str(self.get_ref().infcx), sty_a,
b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx), sty_a,
b.repr(self.get_ref().infcx.tcx));

let sub = Sub(self.get_ref().clone());
let coercion = Coercion(self.get_ref().trace.clone());
Expand Down Expand Up @@ -336,8 +336,8 @@ impl<'f> Coerce<'f> {
b_mutbl: ast::Mutability) -> CoerceResult
{
debug!("coerce_borrowed_object(a={}, sty_a={:?}, b={})",
a.inf_str(self.get_ref().infcx), sty_a,
b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx), sty_a,
b.repr(self.get_ref().infcx.tcx));

let tcx = self.get_ref().infcx.tcx;
let coercion = Coercion(self.get_ref().trace.clone());
Expand Down Expand Up @@ -376,8 +376,8 @@ impl<'f> Coerce<'f> {
b: ty::t)
-> CoerceResult {
debug!("coerce_borrowed_fn(a={}, sty_a={:?}, b={})",
a.inf_str(self.get_ref().infcx), sty_a,
b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx), sty_a,
b.repr(self.get_ref().infcx.tcx));

match *sty_a {
ty::ty_bare_fn(ref f) => {
Expand All @@ -400,7 +400,7 @@ impl<'f> Coerce<'f> {
self.unpack_actual_value(b, |sty_b| {

debug!("coerce_from_bare_fn(a={}, b={})",
a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx));

if fn_ty_a.abi != abi::Rust || fn_ty_a.fn_style != ast::NormalFn {
return self.subtype(a, b);
Expand Down Expand Up @@ -429,8 +429,8 @@ impl<'f> Coerce<'f> {
mt_b: ty::mt)
-> CoerceResult {
debug!("coerce_unsafe_ptr(a={}, sty_a={:?}, b={})",
a.inf_str(self.get_ref().infcx), sty_a,
b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx), sty_a,
b.repr(self.get_ref().infcx.tcx));

let mt_a = match *sty_a {
ty::ty_rptr(_, mt) => mt,
Expand Down Expand Up @@ -462,8 +462,8 @@ impl<'f> Coerce<'f> {
bounds: ty::BuiltinBounds) -> CoerceResult {

debug!("coerce_object(a={}, sty_a={:?}, b={})",
a.inf_str(self.get_ref().infcx), sty_a,
b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx), sty_a,
b.repr(self.get_ref().infcx.tcx));

Ok(Some(ty::AutoObject(trait_store, bounds,
trait_def_id, trait_substs.clone())))
Expand Down
9 changes: 4 additions & 5 deletions src/librustc/middle/typeck/infer/combine.rs
Expand Up @@ -57,8 +57,7 @@ use middle::typeck::infer::{ToUres};
use middle::typeck::infer::glb::Glb;
use middle::typeck::infer::lub::Lub;
use middle::typeck::infer::sub::Sub;
use middle::typeck::infer::to_str::InferStr;
use middle::typeck::infer::unify::InferCtxtMethods;
use middle::typeck::infer::unify::InferCtxtMethodsForSimplyUnifiableTypes;
use middle::typeck::infer::{InferCtxt, cres, ures};
use middle::typeck::infer::{TypeTrace};
use util::common::indent;
Expand Down Expand Up @@ -263,7 +262,7 @@ pub trait Combine {
a: ty::TraitStore,
b: ty::TraitStore)
-> cres<ty::TraitStore> {
debug!("{}.trait_stores(a={:?}, b={:?})", self.tag(), a, b);
debug!("{}.trait_stores(a={}, b={})", self.tag(), a, b);

match (a, b) {
(ty::RegionTraitStore(a_r, a_m),
Expand Down Expand Up @@ -409,8 +408,8 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
tcx.sess.bug(
format!("{}: bot and var types should have been handled ({},{})",
this.tag(),
a.inf_str(this.infcx()),
b.inf_str(this.infcx())).as_slice());
a.repr(this.infcx().tcx),
b.repr(this.infcx().tcx)).as_slice());
}

// Relate integral variables to other types
Expand Down
29 changes: 14 additions & 15 deletions src/librustc/middle/typeck/infer/glb.rs
Expand Up @@ -17,16 +17,17 @@ use middle::typeck::infer::combine::*;
use middle::typeck::infer::lattice::*;
use middle::typeck::infer::lub::Lub;
use middle::typeck::infer::sub::Sub;
use middle::typeck::infer::to_str::InferStr;
use middle::typeck::infer::{cres, InferCtxt};
use middle::typeck::infer::{TypeTrace, Subtype};
use middle::typeck::infer::fold_regions_in_sig;
use middle::typeck::infer::region_inference::RegionMark;
use syntax::ast::{Many, Once, MutImmutable, MutMutable};
use syntax::ast::{NormalFn, UnsafeFn, NodeId};
use syntax::ast::{Onceness, FnStyle};
use std::collections::HashMap;
use util::common::{indenter};
use util::ppaux::mt_to_str;
use util::ppaux::Repr;

pub struct Glb<'f>(pub CombineFields<'f>); // "greatest lower bound" (common subtype)

Expand Down Expand Up @@ -104,8 +105,8 @@ impl<'f> Combine for Glb<'f> {
fn regions(&self, a: ty::Region, b: ty::Region) -> cres<ty::Region> {
debug!("{}.regions({:?}, {:?})",
self.tag(),
a.inf_str(self.get_ref().infcx),
b.inf_str(self.get_ref().infcx));
a.repr(self.get_ref().infcx.tcx),
b.repr(self.get_ref().infcx.tcx));

Ok(self.get_ref().infcx.region_vars.glb_regions(Subtype(self.trace()), a, b))
}
Expand All @@ -124,14 +125,12 @@ impl<'f> Combine for Glb<'f> {
// please see the large comment in `region_inference.rs`.

debug!("{}.fn_sigs({:?}, {:?})",
self.tag(), a.inf_str(self.get_ref().infcx), b.inf_str(self.get_ref().infcx));
self.tag(), a.repr(self.get_ref().infcx.tcx), b.repr(self.get_ref().infcx.tcx));
let _indenter = indenter();

// Take a snapshot. We'll never roll this back, but in later
// phases we do want to be able to examine "all bindings that
// were created as part of this type comparison", and making a
// snapshot is a convenient way to do that.
let snapshot = self.get_ref().infcx.region_vars.start_snapshot();
// Make a mark so we can examine "all bindings that were
// created as part of this type comparison".
let mark = self.get_ref().infcx.region_vars.mark();

// Instantiate each bound region with a fresh region variable.
let (a_with_fresh, a_map) =
Expand All @@ -145,30 +144,30 @@ impl<'f> Combine for Glb<'f> {

// Collect constraints.
let sig0 = if_ok!(super_fn_sigs(self, &a_with_fresh, &b_with_fresh));
debug!("sig0 = {}", sig0.inf_str(self.get_ref().infcx));
debug!("sig0 = {}", sig0.repr(self.get_ref().infcx.tcx));

// Generalize the regions appearing in fn_ty0 if possible
let new_vars =
self.get_ref().infcx.region_vars.vars_created_since_snapshot(snapshot);
self.get_ref().infcx.region_vars.vars_created_since_mark(mark);
let sig1 =
fold_regions_in_sig(
self.get_ref().infcx.tcx,
&sig0,
|r| {
generalize_region(self,
snapshot,
mark,
new_vars.as_slice(),
sig0.binder_id,
&a_map,
a_vars.as_slice(),
b_vars.as_slice(),
r)
});
debug!("sig1 = {}", sig1.inf_str(self.get_ref().infcx));
debug!("sig1 = {}", sig1.repr(self.get_ref().infcx.tcx));
return Ok(sig1);

fn generalize_region(this: &Glb,
snapshot: uint,
mark: RegionMark,
new_vars: &[RegionVid],
new_binder_id: NodeId,
a_map: &HashMap<ty::BoundRegion, ty::Region>,
Expand All @@ -180,7 +179,7 @@ impl<'f> Combine for Glb<'f> {
return r0;
}

let tainted = this.get_ref().infcx.region_vars.tainted(snapshot, r0);
let tainted = this.get_ref().infcx.region_vars.tainted(mark, r0);

let mut a_r = None;
let mut b_r = None;
Expand Down

5 comments on commit 020373f

@bors
Copy link
Contributor

@bors bors commented on 020373f Jun 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from pnkfelix
at nikomatsakis@020373f

@bors
Copy link
Contributor

@bors bors commented on 020373f Jun 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging nikomatsakis/rust/issue-5527-unify-refactor = 020373f into auto

@bors
Copy link
Contributor

@bors bors commented on 020373f Jun 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nikomatsakis/rust/issue-5527-unify-refactor = 020373f merged ok, testing candidate = e8c12d3

@bors
Copy link
Contributor

@bors bors commented on 020373f Jun 24, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = e8c12d3

Please sign in to comment.