Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8403b82

Browse files
committedMar 31, 2015
Port over type inference to using the new type relation stuff
1 parent e301d7c commit 8403b82

File tree

19 files changed

+1140
-955
lines changed

19 files changed

+1140
-955
lines changed
 

‎src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ pub mod middle {
122122
pub mod traits;
123123
pub mod ty;
124124
pub mod ty_fold;
125+
pub mod ty_relate;
125126
pub mod ty_walk;
126127
pub mod weak_lang_items;
127128
}

‎src/librustc/middle/infer/bivariate.rs

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -25,66 +25,54 @@
2525
//! In particular, it might be enough to say (A,B) are bivariant for
2626
//! all (A,B).
2727
28-
use middle::ty::BuiltinBounds;
28+
use super::combine::{self, CombineFields};
29+
use super::type_variable::{BiTo};
30+
2931
use middle::ty::{self, Ty};
3032
use middle::ty::TyVar;
31-
use middle::infer::combine::*;
32-
use middle::infer::CombineResult;
33-
use middle::infer::type_variable::BiTo;
34-
use util::ppaux::Repr;
33+
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
34+
use util::ppaux::{Repr};
3535

36-
pub struct Bivariate<'f, 'tcx: 'f> {
37-
fields: CombineFields<'f, 'tcx>
36+
pub struct Bivariate<'a, 'tcx: 'a> {
37+
fields: CombineFields<'a, 'tcx>
3838
}
3939

40-
#[allow(non_snake_case)]
41-
pub fn Bivariate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Bivariate<'f, 'tcx> {
42-
Bivariate { fields: cf }
40+
impl<'a, 'tcx> Bivariate<'a, 'tcx> {
41+
pub fn new(fields: CombineFields<'a, 'tcx>) -> Bivariate<'a, 'tcx> {
42+
Bivariate { fields: fields }
43+
}
4344
}
4445

45-
impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> {
46-
fn tag(&self) -> String { "Bivariate".to_string() }
47-
fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
46+
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
47+
fn tag(&self) -> &'static str { "Bivariate" }
4848

49-
fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
50-
-> CombineResult<'tcx, Ty<'tcx>>
51-
{
52-
match v {
53-
ty::Invariant => self.equate().tys(a, b),
54-
ty::Covariant => self.tys(a, b),
55-
ty::Contravariant => self.tys(a, b),
56-
ty::Bivariant => self.tys(a, b),
57-
}
58-
}
49+
fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() }
5950

60-
fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
61-
-> CombineResult<'tcx, ty::Region>
62-
{
63-
match v {
64-
ty::Invariant => self.equate().regions(a, b),
65-
ty::Covariant => self.regions(a, b),
66-
ty::Contravariant => self.regions(a, b),
67-
ty::Bivariant => self.regions(a, b),
68-
}
69-
}
51+
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
7052

71-
fn regions(&self, a: ty::Region, _: ty::Region) -> CombineResult<'tcx, ty::Region> {
72-
Ok(a)
73-
}
74-
75-
fn builtin_bounds(&self,
76-
a: BuiltinBounds,
77-
b: BuiltinBounds)
78-
-> CombineResult<'tcx, BuiltinBounds>
53+
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
54+
variance: ty::Variance,
55+
a: &T,
56+
b: &T)
57+
-> RelateResult<'tcx, T>
7958
{
80-
if a != b {
81-
Err(ty::terr_builtin_bounds(expected_found(self, a, b)))
82-
} else {
83-
Ok(a)
59+
match variance {
60+
// If we have Foo<A> and Foo is invariant w/r/t A,
61+
// and we want to assert that
62+
//
63+
// Foo<A> <: Foo<B> ||
64+
// Foo<B> <: Foo<A>
65+
//
66+
// then still A must equal B.
67+
ty::Invariant => self.relate(a, b),
68+
69+
ty::Covariant => self.relate(a, b),
70+
ty::Bivariant => self.relate(a, b),
71+
ty::Contravariant => self.relate(a, b),
8472
}
8573
}
8674

87-
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
75+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
8876
debug!("{}.tys({}, {})", self.tag(),
8977
a.repr(self.fields.infcx.tcx), b.repr(self.fields.infcx.tcx));
9078
if a == b { return Ok(a); }
@@ -109,17 +97,22 @@ impl<'f, 'tcx> Combine<'tcx> for Bivariate<'f, 'tcx> {
10997
}
11098

11199
_ => {
112-
super_tys(self, a, b)
100+
combine::super_combine_tys(self.fields.infcx, self, a, b)
113101
}
114102
}
115103
}
116104

117-
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> CombineResult<'tcx, ty::Binder<T>>
118-
where T : Combineable<'tcx>
105+
fn regions(&mut self, a: ty::Region, _: ty::Region) -> RelateResult<'tcx, ty::Region> {
106+
Ok(a)
107+
}
108+
109+
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
110+
-> RelateResult<'tcx, ty::Binder<T>>
111+
where T: Relate<'a,'tcx>
119112
{
120113
let a1 = ty::erase_late_bound_regions(self.tcx(), a);
121114
let b1 = ty::erase_late_bound_regions(self.tcx(), b);
122-
let c = try!(Combineable::combine(self, &a1, &b1));
115+
let c = try!(self.relate(&a1, &b1));
123116
Ok(ty::Binder(c))
124117
}
125118
}

‎src/librustc/middle/infer/combine.rs

Lines changed: 104 additions & 600 deletions
Large diffs are not rendered by default.

‎src/librustc/middle/infer/equate.rs

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,51 +8,43 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use super::combine::{self, CombineFields};
12+
use super::higher_ranked::HigherRankedRelations;
13+
use super::{Subtype};
14+
use super::type_variable::{EqTo};
15+
1116
use middle::ty::{self, Ty};
1217
use middle::ty::TyVar;
13-
use middle::infer::combine::*;
14-
use middle::infer::CombineResult;
15-
use middle::infer::Subtype;
16-
use middle::infer::type_variable::EqTo;
17-
use util::ppaux::Repr;
18+
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
19+
use util::ppaux::{Repr};
1820

19-
pub struct Equate<'f, 'tcx: 'f> {
20-
fields: CombineFields<'f, 'tcx>
21+
pub struct Equate<'a, 'tcx: 'a> {
22+
fields: CombineFields<'a, 'tcx>
2123
}
2224

23-
#[allow(non_snake_case)]
24-
pub fn Equate<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Equate<'f, 'tcx> {
25-
Equate { fields: cf }
25+
impl<'a, 'tcx> Equate<'a, 'tcx> {
26+
pub fn new(fields: CombineFields<'a, 'tcx>) -> Equate<'a, 'tcx> {
27+
Equate { fields: fields }
28+
}
2629
}
2730

28-
impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
29-
fn tag(&self) -> String { "Equate".to_string() }
30-
fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
31+
impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {
32+
fn tag(&self) -> &'static str { "Equate" }
3133

32-
fn tys_with_variance(&self, _: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
33-
-> CombineResult<'tcx, Ty<'tcx>>
34-
{
35-
// Once we're equating, it doesn't matter what the variance is.
36-
self.tys(a, b)
37-
}
34+
fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() }
3835

39-
fn regions_with_variance(&self, _: ty::Variance, a: ty::Region, b: ty::Region)
40-
-> CombineResult<'tcx, ty::Region>
41-
{
42-
// Once we're equating, it doesn't matter what the variance is.
43-
self.regions(a, b)
44-
}
36+
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
4537

46-
fn regions(&self, a: ty::Region, b: ty::Region) -> CombineResult<'tcx, ty::Region> {
47-
debug!("{}.regions({}, {})",
48-
self.tag(),
49-
a.repr(self.fields.infcx.tcx),
50-
b.repr(self.fields.infcx.tcx));
51-
self.infcx().region_vars.make_eqregion(Subtype(self.trace()), a, b);
52-
Ok(a)
38+
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
39+
_: ty::Variance,
40+
a: &T,
41+
b: &T)
42+
-> RelateResult<'tcx, T>
43+
{
44+
self.relate(a, b)
5345
}
5446

55-
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
47+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
5648
debug!("{}.tys({}, {})", self.tag(),
5749
a.repr(self.fields.infcx.tcx), b.repr(self.fields.infcx.tcx));
5850
if a == b { return Ok(a); }
@@ -77,15 +69,26 @@ impl<'f, 'tcx> Combine<'tcx> for Equate<'f, 'tcx> {
7769
}
7870

7971
_ => {
80-
super_tys(self, a, b)
72+
combine::super_combine_tys(self.fields.infcx, self, a, b)
8173
}
8274
}
8375
}
8476

85-
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> CombineResult<'tcx, ty::Binder<T>>
86-
where T : Combineable<'tcx>
77+
fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
78+
debug!("{}.regions({}, {})",
79+
self.tag(),
80+
a.repr(self.fields.infcx.tcx),
81+
b.repr(self.fields.infcx.tcx));
82+
let origin = Subtype(self.fields.trace.clone());
83+
self.fields.infcx.region_vars.make_eqregion(origin, a, b);
84+
Ok(a)
85+
}
86+
87+
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
88+
-> RelateResult<'tcx, ty::Binder<T>>
89+
where T: Relate<'a, 'tcx>
8790
{
88-
try!(self.sub().binders(a, b));
89-
self.sub().binders(b, a)
91+
try!(self.fields.higher_ranked_sub(a, b));
92+
self.fields.higher_ranked_sub(b, a)
9093
}
9194
}

‎src/librustc/middle/infer/glb.rs

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,67 +8,79 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::combine::*;
12-
use super::lattice::*;
11+
use super::combine::CombineFields;
1312
use super::higher_ranked::HigherRankedRelations;
14-
use super::CombineResult;
13+
use super::InferCtxt;
14+
use super::lattice::{self, LatticeDir};
1515
use super::Subtype;
1616

1717
use middle::ty::{self, Ty};
18+
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
1819
use util::ppaux::Repr;
1920

2021
/// "Greatest lower bound" (common subtype)
21-
pub struct Glb<'f, 'tcx: 'f> {
22-
fields: CombineFields<'f, 'tcx>
22+
pub struct Glb<'a, 'tcx: 'a> {
23+
fields: CombineFields<'a, 'tcx>
2324
}
2425

25-
#[allow(non_snake_case)]
26-
pub fn Glb<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Glb<'f, 'tcx> {
27-
Glb { fields: cf }
26+
impl<'a, 'tcx> Glb<'a, 'tcx> {
27+
pub fn new(fields: CombineFields<'a, 'tcx>) -> Glb<'a, 'tcx> {
28+
Glb { fields: fields }
29+
}
2830
}
2931

30-
impl<'f, 'tcx> Combine<'tcx> for Glb<'f, 'tcx> {
31-
fn tag(&self) -> String { "Glb".to_string() }
32-
fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
32+
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> {
33+
fn tag(&self) -> &'static str { "Glb" }
34+
35+
fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() }
36+
37+
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
3338

34-
fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
35-
-> CombineResult<'tcx, Ty<'tcx>>
39+
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
40+
variance: ty::Variance,
41+
a: &T,
42+
b: &T)
43+
-> RelateResult<'tcx, T>
3644
{
37-
match v {
38-
ty::Invariant => self.equate().tys(a, b),
39-
ty::Covariant => self.tys(a, b),
40-
ty::Bivariant => self.bivariate().tys(a, b),
41-
ty::Contravariant => self.lub().tys(a, b),
45+
match variance {
46+
ty::Invariant => self.fields.equate().relate(a, b),
47+
ty::Covariant => self.relate(a, b),
48+
ty::Bivariant => self.fields.bivariate().relate(a, b),
49+
ty::Contravariant => self.fields.lub().relate(a, b),
4250
}
4351
}
4452

45-
fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
46-
-> CombineResult<'tcx, ty::Region>
47-
{
48-
match v {
49-
ty::Invariant => self.equate().regions(a, b),
50-
ty::Covariant => self.regions(a, b),
51-
ty::Bivariant => self.bivariate().regions(a, b),
52-
ty::Contravariant => self.lub().regions(a, b),
53-
}
53+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
54+
lattice::super_lattice_tys(self, a, b)
5455
}
5556

56-
fn regions(&self, a: ty::Region, b: ty::Region) -> CombineResult<'tcx, ty::Region> {
57+
fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
5758
debug!("{}.regions({}, {})",
5859
self.tag(),
5960
a.repr(self.fields.infcx.tcx),
6061
b.repr(self.fields.infcx.tcx));
6162

62-
Ok(self.fields.infcx.region_vars.glb_regions(Subtype(self.trace()), a, b))
63+
let origin = Subtype(self.fields.trace.clone());
64+
Ok(self.fields.infcx.region_vars.glb_regions(origin, a, b))
6365
}
6466

65-
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
66-
super_lattice_tys(self, a, b)
67+
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
68+
-> RelateResult<'tcx, ty::Binder<T>>
69+
where T: Relate<'a, 'tcx>
70+
{
71+
self.fields.higher_ranked_glb(a, b)
6772
}
73+
}
6874

69-
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> CombineResult<'tcx, ty::Binder<T>>
70-
where T : Combineable<'tcx>
71-
{
72-
self.higher_ranked_glb(a, b)
75+
impl<'a, 'tcx> LatticeDir<'a,'tcx> for Glb<'a, 'tcx> {
76+
fn infcx(&self) -> &'a InferCtxt<'a,'tcx> {
77+
self.fields.infcx
78+
}
79+
80+
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
81+
let mut sub = self.fields.sub();
82+
try!(sub.relate(&v, &a));
83+
try!(sub.relate(&v, &b));
84+
Ok(())
7385
}
7486
}

‎src/librustc/middle/infer/higher_ranked/mod.rs

Lines changed: 66 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,26 @@
1111
//! Helper routines for higher-ranked things. See the `doc` module at
1212
//! the end of the file for details.
1313
14-
use super::{CombinedSnapshot, CombineResult, InferCtxt, HigherRankedType, SkolemizationMap};
15-
use super::combine::{Combine, Combineable};
14+
use super::{CombinedSnapshot, InferCtxt, HigherRankedType, SkolemizationMap};
15+
use super::combine::CombineFields;
1616

1717
use middle::subst;
1818
use middle::ty::{self, Binder};
1919
use middle::ty_fold::{self, TypeFoldable};
20+
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
2021
use syntax::codemap::Span;
2122
use util::nodemap::{FnvHashMap, FnvHashSet};
2223
use util::ppaux::Repr;
2324

24-
pub trait HigherRankedRelations<'tcx> {
25-
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> CombineResult<'tcx, Binder<T>>
26-
where T : Combineable<'tcx>;
25+
pub trait HigherRankedRelations<'a,'tcx> {
26+
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
27+
where T: Relate<'a,'tcx>;
2728

28-
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> CombineResult<'tcx, Binder<T>>
29-
where T : Combineable<'tcx>;
29+
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
30+
where T: Relate<'a,'tcx>;
3031

31-
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> CombineResult<'tcx, Binder<T>>
32-
where T : Combineable<'tcx>;
32+
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
33+
where T: Relate<'a,'tcx>;
3334
}
3435

3536
trait InferCtxtExt {
@@ -40,15 +41,15 @@ trait InferCtxtExt {
4041
-> Vec<ty::RegionVid>;
4142
}
4243

43-
impl<'tcx,C> HigherRankedRelations<'tcx> for C
44-
where C : Combine<'tcx>
45-
{
44+
impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
4645
fn higher_ranked_sub<T>(&self, a: &Binder<T>, b: &Binder<T>)
47-
-> CombineResult<'tcx, Binder<T>>
48-
where T : Combineable<'tcx>
46+
-> RelateResult<'tcx, Binder<T>>
47+
where T: Relate<'a,'tcx>
4948
{
49+
let tcx = self.infcx.tcx;
50+
5051
debug!("higher_ranked_sub(a={}, b={})",
51-
a.repr(self.tcx()), b.repr(self.tcx()));
52+
a.repr(tcx), b.repr(tcx));
5253

5354
// Rather than checking the subtype relationship between `a` and `b`
5455
// as-is, we need to do some extra work here in order to make sure
@@ -60,32 +61,32 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
6061

6162
// Start a snapshot so we can examine "all bindings that were
6263
// created as part of this type comparison".
63-
return self.infcx().commit_if_ok(|snapshot| {
64+
return self.infcx.commit_if_ok(|snapshot| {
6465
// First, we instantiate each bound region in the subtype with a fresh
6566
// region variable.
6667
let (a_prime, _) =
67-
self.infcx().replace_late_bound_regions_with_fresh_var(
68-
self.trace().origin.span(),
68+
self.infcx.replace_late_bound_regions_with_fresh_var(
69+
self.trace.origin.span(),
6970
HigherRankedType,
7071
a);
7172

7273
// Second, we instantiate each bound region in the supertype with a
7374
// fresh concrete region.
7475
let (b_prime, skol_map) =
75-
self.infcx().skolemize_late_bound_regions(b, snapshot);
76+
self.infcx.skolemize_late_bound_regions(b, snapshot);
7677

77-
debug!("a_prime={}", a_prime.repr(self.tcx()));
78-
debug!("b_prime={}", b_prime.repr(self.tcx()));
78+
debug!("a_prime={}", a_prime.repr(tcx));
79+
debug!("b_prime={}", b_prime.repr(tcx));
7980

8081
// Compare types now that bound regions have been replaced.
81-
let result = try!(Combineable::combine(self, &a_prime, &b_prime));
82+
let result = try!(self.sub().relate(&a_prime, &b_prime));
8283

8384
// Presuming type comparison succeeds, we need to check
8485
// that the skolemized regions do not "leak".
85-
match leak_check(self.infcx(), &skol_map, snapshot) {
86+
match leak_check(self.infcx, &skol_map, snapshot) {
8687
Ok(()) => { }
8788
Err((skol_br, tainted_region)) => {
88-
if self.a_is_expected() {
89+
if self.a_is_expected {
8990
debug!("Not as polymorphic!");
9091
return Err(ty::terr_regions_insufficiently_polymorphic(skol_br,
9192
tainted_region));
@@ -98,42 +99,42 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
9899
}
99100

100101
debug!("higher_ranked_sub: OK result={}",
101-
result.repr(self.tcx()));
102+
result.repr(tcx));
102103

103104
Ok(ty::Binder(result))
104105
});
105106
}
106107

107-
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> CombineResult<'tcx, Binder<T>>
108-
where T : Combineable<'tcx>
108+
fn higher_ranked_lub<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
109+
where T: Relate<'a,'tcx>
109110
{
110111
// Start a snapshot so we can examine "all bindings that were
111112
// created as part of this type comparison".
112-
return self.infcx().commit_if_ok(|snapshot| {
113+
return self.infcx.commit_if_ok(|snapshot| {
113114
// Instantiate each bound region with a fresh region variable.
114-
let span = self.trace().origin.span();
115+
let span = self.trace.origin.span();
115116
let (a_with_fresh, a_map) =
116-
self.infcx().replace_late_bound_regions_with_fresh_var(
117+
self.infcx.replace_late_bound_regions_with_fresh_var(
117118
span, HigherRankedType, a);
118119
let (b_with_fresh, _) =
119-
self.infcx().replace_late_bound_regions_with_fresh_var(
120+
self.infcx.replace_late_bound_regions_with_fresh_var(
120121
span, HigherRankedType, b);
121122

122123
// Collect constraints.
123124
let result0 =
124-
try!(Combineable::combine(self, &a_with_fresh, &b_with_fresh));
125+
try!(self.lub().relate(&a_with_fresh, &b_with_fresh));
125126
let result0 =
126-
self.infcx().resolve_type_vars_if_possible(&result0);
127+
self.infcx.resolve_type_vars_if_possible(&result0);
127128
debug!("lub result0 = {}", result0.repr(self.tcx()));
128129

129130
// Generalize the regions appearing in result0 if possible
130-
let new_vars = self.infcx().region_vars_confined_to_snapshot(snapshot);
131-
let span = self.trace().origin.span();
131+
let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot);
132+
let span = self.trace.origin.span();
132133
let result1 =
133134
fold_regions_in(
134135
self.tcx(),
135136
&result0,
136-
|r, debruijn| generalize_region(self.infcx(), span, snapshot, debruijn,
137+
|r, debruijn| generalize_region(self.infcx, span, snapshot, debruijn,
137138
&new_vars, &a_map, r));
138139

139140
debug!("lub({},{}) = {}",
@@ -194,40 +195,40 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
194195
}
195196
}
196197

197-
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> CombineResult<'tcx, Binder<T>>
198-
where T : Combineable<'tcx>
198+
fn higher_ranked_glb<T>(&self, a: &Binder<T>, b: &Binder<T>) -> RelateResult<'tcx, Binder<T>>
199+
where T: Relate<'a,'tcx>
199200
{
200-
debug!("{}.higher_ranked_glb({}, {})",
201-
self.tag(), a.repr(self.tcx()), b.repr(self.tcx()));
201+
debug!("higher_ranked_glb({}, {})",
202+
a.repr(self.tcx()), b.repr(self.tcx()));
202203

203204
// Make a snapshot so we can examine "all bindings that were
204205
// created as part of this type comparison".
205-
return self.infcx().commit_if_ok(|snapshot| {
206+
return self.infcx.commit_if_ok(|snapshot| {
206207
// Instantiate each bound region with a fresh region variable.
207208
let (a_with_fresh, a_map) =
208-
self.infcx().replace_late_bound_regions_with_fresh_var(
209-
self.trace().origin.span(), HigherRankedType, a);
209+
self.infcx.replace_late_bound_regions_with_fresh_var(
210+
self.trace.origin.span(), HigherRankedType, a);
210211
let (b_with_fresh, b_map) =
211-
self.infcx().replace_late_bound_regions_with_fresh_var(
212-
self.trace().origin.span(), HigherRankedType, b);
212+
self.infcx.replace_late_bound_regions_with_fresh_var(
213+
self.trace.origin.span(), HigherRankedType, b);
213214
let a_vars = var_ids(self, &a_map);
214215
let b_vars = var_ids(self, &b_map);
215216

216217
// Collect constraints.
217218
let result0 =
218-
try!(Combineable::combine(self, &a_with_fresh, &b_with_fresh));
219+
try!(self.glb().relate(&a_with_fresh, &b_with_fresh));
219220
let result0 =
220-
self.infcx().resolve_type_vars_if_possible(&result0);
221+
self.infcx.resolve_type_vars_if_possible(&result0);
221222
debug!("glb result0 = {}", result0.repr(self.tcx()));
222223

223224
// Generalize the regions appearing in result0 if possible
224-
let new_vars = self.infcx().region_vars_confined_to_snapshot(snapshot);
225-
let span = self.trace().origin.span();
225+
let new_vars = self.infcx.region_vars_confined_to_snapshot(snapshot);
226+
let span = self.trace.origin.span();
226227
let result1 =
227228
fold_regions_in(
228229
self.tcx(),
229230
&result0,
230-
|r, debruijn| generalize_region(self.infcx(), span, snapshot, debruijn,
231+
|r, debruijn| generalize_region(self.infcx, span, snapshot, debruijn,
231232
&new_vars,
232233
&a_map, &a_vars, &b_vars,
233234
r));
@@ -332,17 +333,19 @@ impl<'tcx,C> HigherRankedRelations<'tcx> for C
332333
}
333334
}
334335

335-
fn var_ids<'tcx, T: Combine<'tcx>>(combiner: &T,
336-
map: &FnvHashMap<ty::BoundRegion, ty::Region>)
337-
-> Vec<ty::RegionVid> {
338-
map.iter().map(|(_, r)| match *r {
339-
ty::ReInfer(ty::ReVar(r)) => { r }
340-
r => {
341-
combiner.infcx().tcx.sess.span_bug(
342-
combiner.trace().origin.span(),
343-
&format!("found non-region-vid: {:?}", r));
344-
}
345-
}).collect()
336+
fn var_ids<'a, 'tcx>(fields: &CombineFields<'a, 'tcx>,
337+
map: &FnvHashMap<ty::BoundRegion, ty::Region>)
338+
-> Vec<ty::RegionVid> {
339+
map.iter()
340+
.map(|(_, r)| match *r {
341+
ty::ReInfer(ty::ReVar(r)) => { r }
342+
r => {
343+
fields.tcx().sess.span_bug(
344+
fields.trace.origin.span(),
345+
&format!("found non-region-vid: {:?}", r));
346+
}
347+
})
348+
.collect()
346349
}
347350

348351
fn is_var_in_set(new_vars: &[ty::RegionVid], r: ty::Region) -> bool {
@@ -356,8 +359,8 @@ fn fold_regions_in<'tcx, T, F>(tcx: &ty::ctxt<'tcx>,
356359
unbound_value: &T,
357360
mut fldr: F)
358361
-> T
359-
where T : Combineable<'tcx>,
360-
F : FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
362+
where T: TypeFoldable<'tcx>,
363+
F: FnMut(ty::Region, ty::DebruijnIndex) -> ty::Region,
361364
{
362365
unbound_value.fold_with(&mut ty_fold::RegionFolder::new(tcx, &mut |region, current_depth| {
363366
// we should only be encountering "escaping" late-bound regions here,

‎src/librustc/middle/infer/lattice.rs

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,48 +29,32 @@
2929
//! over a `LatticeValue`, which is a value defined with respect to
3030
//! a lattice.
3131
32-
use super::*;
33-
use super::combine::*;
34-
use super::glb::Glb;
35-
use super::lub::Lub;
32+
use super::combine;
33+
use super::InferCtxt;
3634

3735
use middle::ty::TyVar;
3836
use middle::ty::{self, Ty};
37+
use middle::ty_relate::{RelateResult, TypeRelation};
3938
use util::ppaux::Repr;
4039

41-
pub trait LatticeDir<'tcx> {
40+
pub trait LatticeDir<'f,'tcx> : TypeRelation<'f,'tcx> {
41+
fn infcx(&self) -> &'f InferCtxt<'f, 'tcx>;
42+
4243
// Relates the type `v` to `a` and `b` such that `v` represents
4344
// the LUB/GLB of `a` and `b` as appropriate.
44-
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, ()>;
45-
}
46-
47-
impl<'a, 'tcx> LatticeDir<'tcx> for Lub<'a, 'tcx> {
48-
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, ()> {
49-
let sub = self.sub();
50-
try!(sub.tys(a, v));
51-
try!(sub.tys(b, v));
52-
Ok(())
53-
}
54-
}
55-
56-
impl<'a, 'tcx> LatticeDir<'tcx> for Glb<'a, 'tcx> {
57-
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, ()> {
58-
let sub = self.sub();
59-
try!(sub.tys(v, a));
60-
try!(sub.tys(v, b));
61-
Ok(())
62-
}
45+
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()>;
6346
}
6447

65-
pub fn super_lattice_tys<'tcx, L:LatticeDir<'tcx>+Combine<'tcx>>(this: &L,
66-
a: Ty<'tcx>,
67-
b: Ty<'tcx>)
68-
-> CombineResult<'tcx, Ty<'tcx>>
48+
pub fn super_lattice_tys<'a,'tcx,L:LatticeDir<'a,'tcx>>(this: &mut L,
49+
a: Ty<'tcx>,
50+
b: Ty<'tcx>)
51+
-> RelateResult<'tcx, Ty<'tcx>>
52+
where 'tcx: 'a
6953
{
7054
debug!("{}.lattice_tys({}, {})",
7155
this.tag(),
72-
a.repr(this.infcx().tcx),
73-
b.repr(this.infcx().tcx));
56+
a.repr(this.tcx()),
57+
b.repr(this.tcx()));
7458

7559
if a == b {
7660
return Ok(a);
@@ -95,7 +79,7 @@ pub fn super_lattice_tys<'tcx, L:LatticeDir<'tcx>+Combine<'tcx>>(this: &L,
9579
}
9680

9781
_ => {
98-
super_tys(this, a, b)
82+
combine::super_combine_tys(this.infcx(), this, a, b)
9983
}
10084
}
10185
}

‎src/librustc/middle/infer/lub.rs

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,67 +8,80 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::combine::*;
11+
use super::combine::CombineFields;
1212
use super::higher_ranked::HigherRankedRelations;
13-
use super::lattice::*;
14-
use super::CombineResult;
13+
use super::InferCtxt;
14+
use super::lattice::{self, LatticeDir};
1515
use super::Subtype;
1616

1717
use middle::ty::{self, Ty};
18+
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
1819
use util::ppaux::Repr;
1920

2021
/// "Least upper bound" (common supertype)
21-
pub struct Lub<'f, 'tcx: 'f> {
22-
fields: CombineFields<'f, 'tcx>
22+
pub struct Lub<'a, 'tcx: 'a> {
23+
fields: CombineFields<'a, 'tcx>
2324
}
2425

25-
#[allow(non_snake_case)]
26-
pub fn Lub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Lub<'f, 'tcx> {
27-
Lub { fields: cf }
26+
impl<'a, 'tcx> Lub<'a, 'tcx> {
27+
pub fn new(fields: CombineFields<'a, 'tcx>) -> Lub<'a, 'tcx> {
28+
Lub { fields: fields }
29+
}
2830
}
2931

30-
impl<'f, 'tcx> Combine<'tcx> for Lub<'f, 'tcx> {
31-
fn tag(&self) -> String { "Lub".to_string() }
32-
fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
32+
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> {
33+
fn tag(&self) -> &'static str { "Lub" }
34+
35+
fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.tcx() }
36+
37+
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
3338

34-
fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
35-
-> CombineResult<'tcx, Ty<'tcx>>
39+
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
40+
variance: ty::Variance,
41+
a: &T,
42+
b: &T)
43+
-> RelateResult<'tcx, T>
3644
{
37-
match v {
38-
ty::Invariant => self.equate().tys(a, b),
39-
ty::Covariant => self.tys(a, b),
40-
ty::Bivariant => self.bivariate().tys(a, b),
41-
ty::Contravariant => self.glb().tys(a, b),
45+
match variance {
46+
ty::Invariant => self.fields.equate().relate(a, b),
47+
ty::Covariant => self.relate(a, b),
48+
ty::Bivariant => self.fields.bivariate().relate(a, b),
49+
ty::Contravariant => self.fields.glb().relate(a, b),
4250
}
4351
}
4452

45-
fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
46-
-> CombineResult<'tcx, ty::Region>
47-
{
48-
match v {
49-
ty::Invariant => self.equate().regions(a, b),
50-
ty::Covariant => self.regions(a, b),
51-
ty::Bivariant => self.bivariate().regions(a, b),
52-
ty::Contravariant => self.glb().regions(a, b),
53-
}
53+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
54+
lattice::super_lattice_tys(self, a, b)
5455
}
5556

56-
fn regions(&self, a: ty::Region, b: ty::Region) -> CombineResult<'tcx, ty::Region> {
57+
fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
5758
debug!("{}.regions({}, {})",
5859
self.tag(),
5960
a.repr(self.tcx()),
6061
b.repr(self.tcx()));
6162

62-
Ok(self.infcx().region_vars.lub_regions(Subtype(self.trace()), a, b))
63+
let origin = Subtype(self.fields.trace.clone());
64+
Ok(self.fields.infcx.region_vars.lub_regions(origin, a, b))
6365
}
6466

65-
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
66-
super_lattice_tys(self, a, b)
67+
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
68+
-> RelateResult<'tcx, ty::Binder<T>>
69+
where T: Relate<'a, 'tcx>
70+
{
71+
self.fields.higher_ranked_lub(a, b)
6772
}
73+
}
6874

69-
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> CombineResult<'tcx, ty::Binder<T>>
70-
where T : Combineable<'tcx>
71-
{
72-
self.higher_ranked_lub(a, b)
75+
impl<'a, 'tcx> LatticeDir<'a,'tcx> for Lub<'a, 'tcx> {
76+
fn infcx(&self) -> &'a InferCtxt<'a,'tcx> {
77+
self.fields.infcx
78+
}
79+
80+
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
81+
let mut sub = self.fields.sub();
82+
try!(sub.relate(&a, &v));
83+
try!(sub.relate(&b, &v));
84+
Ok(())
7385
}
7486
}
87+

‎src/librustc/middle/infer/mod.rs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ use middle::ty::{TyVid, IntVid, FloatVid, RegionVid, UnconstrainedNumeric};
2828
use middle::ty::replace_late_bound_regions;
2929
use middle::ty::{self, Ty};
3030
use middle::ty_fold::{TypeFolder, TypeFoldable};
31-
use std::cell::RefCell;
31+
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
32+
use std::cell::{RefCell};
3233
use std::fmt;
3334
use std::rc::Rc;
3435
use syntax::ast;
@@ -38,11 +39,8 @@ use util::nodemap::FnvHashMap;
3839
use util::ppaux::ty_to_string;
3940
use util::ppaux::{Repr, UserString};
4041

41-
use self::combine::{Combine, Combineable, CombineFields};
42+
use self::combine::CombineFields;
4243
use self::region_inference::{RegionVarBindings, RegionSnapshot};
43-
use self::equate::Equate;
44-
use self::sub::Sub;
45-
use self::lub::Lub;
4644
use self::unify::{ToType, UnificationTable};
4745
use self::error_reporting::ErrorReporting;
4846

@@ -62,9 +60,7 @@ pub mod type_variable;
6260
pub mod unify;
6361

6462
pub type Bound<T> = Option<T>;
65-
66-
pub type CombineResult<'tcx, T> = Result<T,ty::type_err<'tcx>>; // "combine result"
67-
pub type UnitResult<'tcx> = CombineResult<'tcx, ()>; // "unify result"
63+
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
6864
pub type fres<T> = Result<T, fixup_err>; // "fixup result"
6965

7066
pub struct InferCtxt<'a, 'tcx: 'a> {
@@ -343,7 +339,7 @@ pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
343339
values: Types(expected_found(a_is_expected, a, b))
344340
};
345341

346-
let result = cx.commit_if_ok(|_| cx.lub(a_is_expected, trace.clone()).tys(a, b));
342+
let result = cx.commit_if_ok(|_| cx.lub(a_is_expected, trace.clone()).relate(&a, &b));
347343
match result {
348344
Ok(t) => t,
349345
Err(ref err) => {
@@ -374,11 +370,12 @@ pub fn can_mk_subty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
374370
origin: Misc(codemap::DUMMY_SP),
375371
values: Types(expected_found(true, a, b))
376372
};
377-
cx.sub(true, trace).tys(a, b).map(|_| ())
373+
cx.sub(true, trace).relate(&a, &b).map(|_| ())
378374
})
379375
}
380376

381-
pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> UnitResult<'tcx>
377+
pub fn can_mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>, a: Ty<'tcx>, b: Ty<'tcx>)
378+
-> UnitResult<'tcx>
382379
{
383380
cx.can_equate(&a, &b)
384381
}
@@ -473,26 +470,39 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
473470
}
474471
}
475472

476-
fn combine_fields<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
477-
-> CombineFields<'b, 'tcx> {
473+
fn combine_fields(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
474+
-> CombineFields<'a, 'tcx> {
478475
CombineFields {infcx: self,
479476
a_is_expected: a_is_expected,
480477
trace: trace}
481478
}
482479

483-
fn equate<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
484-
-> Equate<'b, 'tcx> {
485-
Equate(self.combine_fields(a_is_expected, trace))
480+
// public so that it can be used from the rustc_driver unit tests
481+
pub fn equate(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
482+
-> equate::Equate<'a, 'tcx>
483+
{
484+
self.combine_fields(a_is_expected, trace).equate()
486485
}
487486

488-
fn sub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
489-
-> Sub<'b, 'tcx> {
490-
Sub(self.combine_fields(a_is_expected, trace))
487+
// public so that it can be used from the rustc_driver unit tests
488+
pub fn sub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
489+
-> sub::Sub<'a, 'tcx>
490+
{
491+
self.combine_fields(a_is_expected, trace).sub()
491492
}
492493

493-
fn lub<'b>(&'b self, a_is_expected: bool, trace: TypeTrace<'tcx>)
494-
-> Lub<'b, 'tcx> {
495-
Lub(self.combine_fields(a_is_expected, trace))
494+
// public so that it can be used from the rustc_driver unit tests
495+
pub fn lub(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
496+
-> lub::Lub<'a, 'tcx>
497+
{
498+
self.combine_fields(a_is_expected, trace).lub()
499+
}
500+
501+
// public so that it can be used from the rustc_driver unit tests
502+
pub fn glb(&'a self, a_is_expected: bool, trace: TypeTrace<'tcx>)
503+
-> glb::Glb<'a, 'tcx>
504+
{
505+
self.combine_fields(a_is_expected, trace).glb()
496506
}
497507

498508
fn start_snapshot(&self) -> CombinedSnapshot {
@@ -631,7 +641,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
631641
debug!("sub_types({} <: {})", a.repr(self.tcx), b.repr(self.tcx));
632642
self.commit_if_ok(|_| {
633643
let trace = TypeTrace::types(origin, a_is_expected, a, b);
634-
self.sub(a_is_expected, trace).tys(a, b).map(|_| ())
644+
self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
635645
})
636646
}
637647

@@ -644,7 +654,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
644654
{
645655
self.commit_if_ok(|_| {
646656
let trace = TypeTrace::types(origin, a_is_expected, a, b);
647-
self.equate(a_is_expected, trace).tys(a, b).map(|_| ())
657+
self.equate(a_is_expected, trace).relate(&a, &b).map(|_| ())
648658
})
649659
}
650660

@@ -663,7 +673,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
663673
origin: origin,
664674
values: TraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
665675
};
666-
self.sub(a_is_expected, trace).trait_refs(&*a, &*b).map(|_| ())
676+
self.sub(a_is_expected, trace).relate(&*a, &*b).map(|_| ())
667677
})
668678
}
669679

@@ -682,7 +692,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
682692
origin: origin,
683693
values: PolyTraitRefs(expected_found(a_is_expected, a.clone(), b.clone()))
684694
};
685-
self.sub(a_is_expected, trace).binders(&a, &b).map(|_| ())
695+
self.sub(a_is_expected, trace).relate(&a, &b).map(|_| ())
686696
})
687697
}
688698

@@ -1045,8 +1055,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10451055
self.region_vars.verify_generic_bound(origin, kind, a, bs);
10461056
}
10471057

1048-
pub fn can_equate<T>(&self, a: &T, b: &T) -> UnitResult<'tcx>
1049-
where T : Combineable<'tcx> + Repr<'tcx>
1058+
pub fn can_equate<'b,T>(&'b self, a: &T, b: &T) -> UnitResult<'tcx>
1059+
where T: Relate<'b,'tcx> + Repr<'tcx>
10501060
{
10511061
debug!("can_equate({}, {})", a.repr(self.tcx), b.repr(self.tcx));
10521062
self.probe(|_| {
@@ -1057,8 +1067,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10571067
let e = self.tcx.types.err;
10581068
let trace = TypeTrace { origin: Misc(codemap::DUMMY_SP),
10591069
values: Types(expected_found(true, e, e)) };
1060-
let eq = self.equate(true, trace);
1061-
Combineable::combine(&eq, a, b)
1070+
self.equate(true, trace).relate(a, b)
10621071
}).map(|_| ())
10631072
}
10641073
}

‎src/librustc/middle/infer/region_inference/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ pub use self::RegionResolutionError::*;
1818
pub use self::VarValue::*;
1919
use self::Classification::*;
2020

21-
use super::CombineResult;
2221
use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace, MiscVariable};
2322

2423
use middle::region;
2524
use middle::ty::{self, Ty};
2625
use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
2726
use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound};
2827
use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
28+
use middle::ty_relate::RelateResult;
2929
use middle::graph;
3030
use middle::graph::{Direction, NodeIndex};
3131
use util::common::indenter;
@@ -825,7 +825,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
825825
fn glb_concrete_regions(&self,
826826
a: Region,
827827
b: Region)
828-
-> CombineResult<'tcx, Region>
828+
-> RelateResult<'tcx, Region>
829829
{
830830
debug!("glb_concrete_regions({:?}, {:?})", a, b);
831831
match (a, b) {
@@ -901,7 +901,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
901901
fn glb_free_regions(&self,
902902
a: &FreeRegion,
903903
b: &FreeRegion)
904-
-> CombineResult<'tcx, ty::Region>
904+
-> RelateResult<'tcx, ty::Region>
905905
{
906906
return match a.cmp(b) {
907907
Less => helper(self, a, b),
@@ -911,7 +911,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
911911

912912
fn helper<'a, 'tcx>(this: &RegionVarBindings<'a, 'tcx>,
913913
a: &FreeRegion,
914-
b: &FreeRegion) -> CombineResult<'tcx, ty::Region>
914+
b: &FreeRegion) -> RelateResult<'tcx, ty::Region>
915915
{
916916
if this.tcx.region_maps.sub_free_region(*a, *b) {
917917
Ok(ty::ReFree(*a))
@@ -930,7 +930,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
930930
region_b: ty::Region,
931931
scope_a: region::CodeExtent,
932932
scope_b: region::CodeExtent)
933-
-> CombineResult<'tcx, Region>
933+
-> RelateResult<'tcx, Region>
934934
{
935935
// We want to generate the intersection of two
936936
// scopes or two free regions. So, if one of

‎src/librustc/middle/infer/sub.rs

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,64 +8,49 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::combine::*;
12-
use super::CombineResult;
11+
use super::combine::{self, CombineFields};
1312
use super::higher_ranked::HigherRankedRelations;
1413
use super::Subtype;
1514
use super::type_variable::{SubtypeOf, SupertypeOf};
1615

1716
use middle::ty::{self, Ty};
1817
use middle::ty::TyVar;
19-
use util::ppaux::Repr;
18+
use middle::ty_relate::{Relate, RelateResult, TypeRelation};
19+
use util::ppaux::{Repr};
2020

2121
/// "Greatest lower bound" (common subtype)
22-
pub struct Sub<'f, 'tcx: 'f> {
23-
fields: CombineFields<'f, 'tcx>
22+
pub struct Sub<'a, 'tcx: 'a> {
23+
fields: CombineFields<'a, 'tcx>
2424
}
2525

26-
#[allow(non_snake_case)]
27-
pub fn Sub<'f, 'tcx>(cf: CombineFields<'f, 'tcx>) -> Sub<'f, 'tcx> {
28-
Sub { fields: cf }
26+
impl<'a, 'tcx> Sub<'a, 'tcx> {
27+
pub fn new(f: CombineFields<'a, 'tcx>) -> Sub<'a, 'tcx> {
28+
Sub { fields: f }
29+
}
2930
}
3031

31-
impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
32-
fn tag(&self) -> String { "Sub".to_string() }
33-
fn fields<'a>(&'a self) -> &'a CombineFields<'a, 'tcx> { &self.fields }
34-
35-
fn tys_with_variance(&self, v: ty::Variance, a: Ty<'tcx>, b: Ty<'tcx>)
36-
-> CombineResult<'tcx, Ty<'tcx>>
37-
{
38-
match v {
39-
ty::Invariant => self.equate().tys(a, b),
40-
ty::Covariant => self.tys(a, b),
41-
ty::Bivariant => self.bivariate().tys(a, b),
42-
ty::Contravariant => Sub(self.fields.switch_expected()).tys(b, a),
43-
}
44-
}
32+
impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Sub<'a, 'tcx> {
33+
fn tag(&self) -> &'static str { "Sub" }
34+
fn tcx(&self) -> &'a ty::ctxt<'tcx> { self.fields.infcx.tcx }
35+
fn a_is_expected(&self) -> bool { self.fields.a_is_expected }
4536

46-
fn regions_with_variance(&self, v: ty::Variance, a: ty::Region, b: ty::Region)
47-
-> CombineResult<'tcx, ty::Region>
37+
fn relate_with_variance<T:Relate<'a,'tcx>>(&mut self,
38+
variance: ty::Variance,
39+
a: &T,
40+
b: &T)
41+
-> RelateResult<'tcx, T>
4842
{
49-
match v {
50-
ty::Invariant => self.equate().regions(a, b),
51-
ty::Covariant => self.regions(a, b),
52-
ty::Bivariant => self.bivariate().regions(a, b),
53-
ty::Contravariant => Sub(self.fields.switch_expected()).regions(b, a),
43+
match variance {
44+
ty::Invariant => self.fields.equate().relate(a, b),
45+
ty::Covariant => self.relate(a, b),
46+
ty::Bivariant => self.fields.bivariate().relate(a, b),
47+
ty::Contravariant => self.fields.switch_expected().sub().relate(b, a),
5448
}
5549
}
5650

57-
fn regions(&self, a: ty::Region, b: ty::Region) -> CombineResult<'tcx, ty::Region> {
58-
debug!("{}.regions({}, {})",
59-
self.tag(),
60-
a.repr(self.tcx()),
61-
b.repr(self.tcx()));
62-
self.infcx().region_vars.make_subregion(Subtype(self.trace()), a, b);
63-
Ok(a)
64-
}
51+
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
52+
debug!("{}.tys({}, {})", self.tag(), a.repr(self.tcx()), b.repr(self.tcx()));
6553

66-
fn tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CombineResult<'tcx, Ty<'tcx>> {
67-
debug!("{}.tys({}, {})", self.tag(),
68-
a.repr(self.tcx()), b.repr(self.tcx()));
6954
if a == b { return Ok(a); }
7055

7156
let infcx = self.fields.infcx;
@@ -80,8 +65,8 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
8065
}
8166
(&ty::ty_infer(TyVar(a_id)), _) => {
8267
try!(self.fields
83-
.switch_expected()
84-
.instantiate(b, SupertypeOf, a_id));
68+
.switch_expected()
69+
.instantiate(b, SupertypeOf, a_id));
8570
Ok(a)
8671
}
8772
(_, &ty::ty_infer(TyVar(b_id))) => {
@@ -94,14 +79,25 @@ impl<'f, 'tcx> Combine<'tcx> for Sub<'f, 'tcx> {
9479
}
9580

9681
_ => {
97-
super_tys(self, a, b)
82+
combine::super_combine_tys(self.fields.infcx, self, a, b)
9883
}
9984
}
10085
}
10186

102-
fn binders<T>(&self, a: &ty::Binder<T>, b: &ty::Binder<T>) -> CombineResult<'tcx, ty::Binder<T>>
103-
where T : Combineable<'tcx>
87+
fn regions(&mut self, a: ty::Region, b: ty::Region) -> RelateResult<'tcx, ty::Region> {
88+
debug!("{}.regions({}, {})",
89+
self.tag(),
90+
a.repr(self.tcx()),
91+
b.repr(self.tcx()));
92+
let origin = Subtype(self.fields.trace.clone());
93+
self.fields.infcx.region_vars.make_subregion(origin, a, b);
94+
Ok(a)
95+
}
96+
97+
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
98+
-> RelateResult<'tcx, ty::Binder<T>>
99+
where T: Relate<'a,'tcx>
104100
{
105-
self.higher_ranked_sub(a, b)
101+
self.fields.higher_ranked_sub(a, b)
106102
}
107103
}

‎src/librustc/middle/traits/project.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ impl<'a,'b,'tcx> TypeFolder<'tcx> for AssociatedTypeNormalizer<'a,'b,'tcx> {
291291
}
292292
}
293293

294+
#[derive(Clone)]
294295
pub struct Normalized<'tcx,T> {
295296
pub value: T,
296297
pub obligations: Vec<PredicateObligation<'tcx>>,

‎src/librustc/middle/ty_fold.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ use middle::subst::VecPerParamSpace;
3939
use middle::ty::{self, Ty};
4040
use middle::traits;
4141
use std::rc::Rc;
42+
use syntax::abi;
43+
use syntax::ast;
4244
use syntax::owned_slice::OwnedSlice;
4345
use util::ppaux::Repr;
4446

@@ -47,7 +49,7 @@ use util::ppaux::Repr;
4749

4850
/// The TypeFoldable trait is implemented for every type that can be folded.
4951
/// Basically, every type that has a corresponding method in TypeFolder.
50-
pub trait TypeFoldable<'tcx> {
52+
pub trait TypeFoldable<'tcx>: Repr<'tcx> + Clone {
5153
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self;
5254
}
5355

@@ -149,12 +151,20 @@ pub trait TypeFolder<'tcx> : Sized {
149151
// can easily refactor the folding into the TypeFolder trait as
150152
// needed.
151153

152-
impl<'tcx> TypeFoldable<'tcx> for () {
153-
fn fold_with<F:TypeFolder<'tcx>>(&self, _: &mut F) -> () {
154-
()
154+
macro_rules! CopyImpls {
155+
($($ty:ty),+) => {
156+
$(
157+
impl<'tcx> TypeFoldable<'tcx> for $ty {
158+
fn fold_with<F:TypeFolder<'tcx>>(&self, _: &mut F) -> $ty {
159+
*self
160+
}
161+
}
162+
)+
155163
}
156164
}
157165

166+
CopyImpls! { (), ast::Unsafety, abi::Abi }
167+
158168
impl<'tcx, T:TypeFoldable<'tcx>, U:TypeFoldable<'tcx>> TypeFoldable<'tcx> for (T, U) {
159169
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> (T, U) {
160170
(self.0.fold_with(folder), self.1.fold_with(folder))

‎src/librustc/middle/ty_relate/mod.rs

Lines changed: 655 additions & 0 deletions
Large diffs are not rendered by default.

‎src/librustc/util/ppaux.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,3 +1532,9 @@ impl<'tcx> UserString<'tcx> for ty::Predicate<'tcx> {
15321532
}
15331533
}
15341534
}
1535+
1536+
impl<'tcx> Repr<'tcx> for ast::Unsafety {
1537+
fn repr(&self, _: &ctxt<'tcx>) -> String {
1538+
format!("{:?}", *self)
1539+
}
1540+
}

‎src/librustc_driver/test.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_typeck::middle::stability;
2222
use rustc_typeck::middle::subst;
2323
use rustc_typeck::middle::subst::Subst;
2424
use rustc_typeck::middle::ty::{self, Ty};
25-
use rustc_typeck::middle::infer::combine::Combine;
25+
use rustc_typeck::middle::ty_relate::TypeRelation;
2626
use rustc_typeck::middle::infer;
2727
use rustc_typeck::middle::infer::lub::Lub;
2828
use rustc_typeck::middle::infer::glb::Glb;
@@ -350,21 +350,21 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
350350

351351
pub fn sub(&self) -> Sub<'a, 'tcx> {
352352
let trace = self.dummy_type_trace();
353-
Sub(self.infcx.combine_fields(true, trace))
353+
self.infcx.sub(true, trace)
354354
}
355355

356356
pub fn lub(&self) -> Lub<'a, 'tcx> {
357357
let trace = self.dummy_type_trace();
358-
Lub(self.infcx.combine_fields(true, trace))
358+
self.infcx.lub(true, trace)
359359
}
360360

361361
pub fn glb(&self) -> Glb<'a, 'tcx> {
362362
let trace = self.dummy_type_trace();
363-
Glb(self.infcx.combine_fields(true, trace))
363+
self.infcx.glb(true, trace)
364364
}
365365

366366
pub fn make_lub_ty(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> Ty<'tcx> {
367-
match self.lub().tys(t1, t2) {
367+
match self.lub().relate(&t1, &t2) {
368368
Ok(t) => t,
369369
Err(ref e) => panic!("unexpected error computing LUB: {}",
370370
ty::type_err_to_str(self.infcx.tcx, e))
@@ -374,7 +374,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
374374
/// Checks that `t1 <: t2` is true (this may register additional
375375
/// region checks).
376376
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
377-
match self.sub().tys(t1, t2) {
377+
match self.sub().relate(&t1, &t2) {
378378
Ok(_) => { }
379379
Err(ref e) => {
380380
panic!("unexpected error computing sub({},{}): {}",
@@ -388,7 +388,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
388388
/// Checks that `t1 <: t2` is false (this may register additional
389389
/// region checks).
390390
pub fn check_not_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
391-
match self.sub().tys(t1, t2) {
391+
match self.sub().relate(&t1, &t2) {
392392
Err(_) => { }
393393
Ok(_) => {
394394
panic!("unexpected success computing sub({},{})",
@@ -400,7 +400,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
400400

401401
/// Checks that `LUB(t1,t2) == t_lub`
402402
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
403-
match self.lub().tys(t1, t2) {
403+
match self.lub().relate(&t1, &t2) {
404404
Ok(t) => {
405405
self.assert_eq(t, t_lub);
406406
}
@@ -417,7 +417,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
417417
self.ty_to_string(t1),
418418
self.ty_to_string(t2),
419419
self.ty_to_string(t_glb));
420-
match self.glb().tys(t1, t2) {
420+
match self.glb().relate(&t1, &t2) {
421421
Err(e) => {
422422
panic!("unexpected error computing LUB: {:?}", e)
423423
}

‎src/librustc_typeck/check/coercion.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@
6262
6363
use check::{autoderef, FnCtxt, NoPreference, PreferMutLvalue, UnresolvedTypeAction};
6464

65-
use middle::infer::{self, CombineResult, Coercion};
66-
use middle::infer::combine::Combine;
65+
use middle::infer::{self, Coercion};
6766
use middle::subst;
6867
use middle::ty::{AutoPtr, AutoDerefRef, AdjustDerefRef, AutoUnsize, AutoUnsafe};
6968
use middle::ty::{self, mt, Ty};
69+
use middle::ty_relate::RelateResult;
7070
use util::common::indent;
7171
use util::ppaux;
7272
use util::ppaux::Repr;
@@ -78,7 +78,7 @@ struct Coerce<'a, 'tcx: 'a> {
7878
origin: infer::TypeOrigin,
7979
}
8080

81-
type CoerceResult<'tcx> = CombineResult<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
81+
type CoerceResult<'tcx> = RelateResult<'tcx, Option<ty::AutoAdjustment<'tcx>>>;
8282

8383
impl<'f, 'tcx> Coerce<'f, 'tcx> {
8484
fn tcx(&self) -> &ty::ctxt<'tcx> {
@@ -536,7 +536,7 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
536536
expr: &ast::Expr,
537537
a: Ty<'tcx>,
538538
b: Ty<'tcx>)
539-
-> CombineResult<'tcx, ()> {
539+
-> RelateResult<'tcx, ()> {
540540
debug!("mk_assignty({} -> {})", a.repr(fcx.tcx()), b.repr(fcx.tcx()));
541541
let adjustment = try!(indent(|| {
542542
fcx.infcx().commit_if_ok(|_| {

‎src/librustc_typeck/coherence/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use middle::ty::{ty_uint, ty_closure, ty_uniq, ty_bare_fn};
3030
use middle::ty::ty_projection;
3131
use middle::ty;
3232
use CrateCtxt;
33-
use middle::infer::combine::Combine;
3433
use middle::infer::InferCtxt;
3534
use middle::infer::new_infer_ctxt;
3635
use std::collections::HashSet;

‎src/test/compile-fail/dst-bad-coerce1.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ pub fn main() {
2323
let f2: &Fat<[isize; 3]> = &f1;
2424
let f3: &Fat<[usize]> = f2;
2525
//~^ ERROR mismatched types
26-
//~| expected `&Fat<[usize]>`
27-
//~| found `&Fat<[isize; 3]>`
28-
//~| expected usize
29-
//~| found isize
3026

3127
// With a trait.
3228
let f1 = Fat { ptr: Foo };

0 commit comments

Comments
 (0)
Please sign in to comment.