Skip to content

Refactor the unification code and rejuvenate the unit test infrastructure #15079

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 24, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 14 additions & 28 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading