Skip to content

Commit e09d1be

Browse files
Plumb inference obligations through librustc/middle
1 parent 57c357d commit e09d1be

File tree

14 files changed

+308
-184
lines changed

14 files changed

+308
-184
lines changed

src/librustc/middle/infer/bivariate.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use super::type_variable::{BiTo};
3030

3131
use middle::ty::{self, Ty};
3232
use middle::ty::TyVar;
33-
use middle::ty::relate::{Relate, RelateResult, TypeRelation};
33+
use middle::ty::relate::{Relate, RelateOk, RelateResult, RelateResultTrait, TypeRelation};
3434

3535
pub struct Bivariate<'a, 'tcx: 'a> {
3636
fields: CombineFields<'a, 'tcx>
@@ -74,25 +74,23 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
7474
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
7575
debug!("{}.tys({:?}, {:?})", self.tag(),
7676
a, b);
77-
if a == b { return Ok(a); }
77+
if a == b { return Ok(RelateOk::from(a)); }
7878

7979
let infcx = self.fields.infcx;
8080
let a = infcx.type_variables.borrow().replace_if_possible(a);
8181
let b = infcx.type_variables.borrow().replace_if_possible(b);
8282
match (&a.sty, &b.sty) {
8383
(&ty::TyInfer(TyVar(a_id)), &ty::TyInfer(TyVar(b_id))) => {
8484
infcx.type_variables.borrow_mut().relate_vars(a_id, BiTo, b_id);
85-
Ok(a)
85+
Ok(RelateOk::from(a))
8686
}
8787

8888
(&ty::TyInfer(TyVar(a_id)), _) => {
89-
try!(self.fields.instantiate(b, BiTo, a_id));
90-
Ok(a)
89+
self.fields.instantiate(b, BiTo, a_id).map_value(|_| a)
9190
}
9291

9392
(_, &ty::TyInfer(TyVar(b_id))) => {
94-
try!(self.fields.instantiate(a, BiTo, b_id));
95-
Ok(a)
93+
self.fields.instantiate(a, BiTo, b_id).map_value(|_| a)
9694
}
9795

9896
_ => {
@@ -102,7 +100,7 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
102100
}
103101

104102
fn regions(&mut self, a: ty::Region, _: ty::Region) -> RelateResult<'tcx, ty::Region> {
105-
Ok(a)
103+
Ok(RelateOk::from(a))
106104
}
107105

108106
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
@@ -111,7 +109,6 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Bivariate<'a, 'tcx> {
111109
{
112110
let a1 = self.tcx().erase_late_bound_regions(a);
113111
let b1 = self.tcx().erase_late_bound_regions(b);
114-
let c = try!(self.relate(&a1, &b1));
115-
Ok(ty::Binder(c))
112+
self.relate(&a1, &b1).map_value(|c| ty::Binder(c))
116113
}
117114
}

src/librustc/middle/infer/combine.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use middle::ty::{IntType, UintType};
4545
use middle::ty::{self, Ty};
4646
use middle::ty::error::TypeError;
4747
use middle::ty::fold::{TypeFolder, TypeFoldable};
48-
use middle::ty::relate::{Relate, RelateResult, TypeRelation};
48+
use middle::ty::relate::{Relate, RelateOk, RelateResult, TypeRelation};
4949

5050
use syntax::ast;
5151
use syntax::codemap::Span;
@@ -74,7 +74,7 @@ pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
7474
.borrow_mut()
7575
.unify_var_var(a_id, b_id)
7676
.map_err(|e| int_unification_error(a_is_expected, e)));
77-
Ok(a)
77+
Ok(RelateOk::from(a))
7878
}
7979
(&ty::TyInfer(ty::IntVar(v_id)), &ty::TyInt(v)) => {
8080
unify_integral_variable(infcx, a_is_expected, v_id, IntType(v))
@@ -95,7 +95,7 @@ pub fn super_combine_tys<'a,'tcx:'a,R>(infcx: &InferCtxt<'a, 'tcx>,
9595
.borrow_mut()
9696
.unify_var_var(a_id, b_id)
9797
.map_err(|e| float_unification_error(relation.a_is_expected(), e)));
98-
Ok(a)
98+
Ok(RelateOk::from(a))
9999
}
100100
(&ty::TyInfer(ty::FloatVar(v_id)), &ty::TyFloat(v)) => {
101101
unify_float_variable(infcx, a_is_expected, v_id, v)
@@ -129,8 +129,8 @@ fn unify_integral_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
129129
.unify_var_value(vid, val)
130130
.map_err(|e| int_unification_error(vid_is_expected, e)));
131131
match val {
132-
IntType(v) => Ok(infcx.tcx.mk_mach_int(v)),
133-
UintType(v) => Ok(infcx.tcx.mk_mach_uint(v)),
132+
IntType(v) => Ok(RelateOk::from(infcx.tcx.mk_mach_int(v))),
133+
UintType(v) => Ok(RelateOk::from(infcx.tcx.mk_mach_uint(v))),
134134
}
135135
}
136136

@@ -145,7 +145,7 @@ fn unify_float_variable<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
145145
.borrow_mut()
146146
.unify_var_value(vid, val)
147147
.map_err(|e| float_unification_error(vid_is_expected, e)));
148-
Ok(infcx.tcx.mk_mach_float(val))
148+
Ok(RelateOk::from(infcx.tcx.mk_mach_float(val)))
149149
}
150150

151151
impl<'a, 'tcx> CombineFields<'a, 'tcx> {
@@ -187,6 +187,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
187187
-> RelateResult<'tcx, ()>
188188
{
189189
let mut stack = Vec::new();
190+
let mut obligations = Vec::new();
190191
stack.push((a_ty, dir, b_vid));
191192
loop {
192193
// For each turn of the loop, we extract a tuple
@@ -224,10 +225,11 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
224225
Some(t) => t, // ...already instantiated.
225226
None => { // ...not yet instantiated:
226227
// Generalize type if necessary.
227-
let generalized_ty = try!(match dir {
228-
EqTo => self.generalize(a_ty, b_vid, false),
229-
BiTo | SupertypeOf | SubtypeOf => self.generalize(a_ty, b_vid, true),
230-
});
228+
let RelateOk { value: generalized_ty, obligations: new_obligations } =
229+
try!(match dir {
230+
EqTo => self.generalize(a_ty, b_vid, false),
231+
BiTo | SupertypeOf | SubtypeOf => self.generalize(a_ty, b_vid, true),
232+
});
231233
debug!("instantiate(a_ty={:?}, dir={:?}, \
232234
b_vid={:?}, generalized_ty={:?})",
233235
a_ty, dir, b_vid,
@@ -236,6 +238,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
236238
.borrow_mut()
237239
.instantiate_and_push(
238240
b_vid, generalized_ty, &mut stack);
241+
obligations.extend(new_obligations);
239242
generalized_ty
240243
}
241244
};
@@ -247,15 +250,16 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
247250
// relations wind up attributed to the same spans. We need
248251
// to associate causes/spans with each of the relations in
249252
// the stack to get this right.
250-
try!(match dir {
253+
let RelateOk { obligations: new_obligations, .. } = try!(match dir {
251254
BiTo => self.bivariate().relate(&a_ty, &b_ty),
252255
EqTo => self.equate().relate(&a_ty, &b_ty),
253256
SubtypeOf => self.sub().relate(&a_ty, &b_ty),
254257
SupertypeOf => self.sub().relate_with_variance(ty::Contravariant, &a_ty, &b_ty),
255258
});
259+
obligations.extend(new_obligations);
256260
}
257261

258-
Ok(())
262+
Ok(RelateOk { value: (), obligations: obligations })
259263
}
260264

261265
/// Attempts to generalize `ty` for the type variable `for_vid`. This checks for cycle -- that
@@ -279,7 +283,7 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
279283
if generalize.cycle_detected {
280284
Err(TypeError::CyclicTy)
281285
} else {
282-
Ok(u)
286+
Ok(RelateOk::from(u))
283287
}
284288
}
285289
}
@@ -370,7 +374,7 @@ impl<'tcx, T:Clone + PartialEq> RelateResultCompare<'tcx, T> for RelateResult<'t
370374
F: FnOnce() -> TypeError<'tcx>,
371375
{
372376
self.clone().and_then(|s| {
373-
if s == t {
377+
if s.value == t {
374378
self.clone()
375379
} else {
376380
Err(f())

src/librustc/middle/infer/equate.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use super::type_variable::{EqTo};
1515

1616
use middle::ty::{self, Ty};
1717
use middle::ty::TyVar;
18-
use middle::ty::relate::{Relate, RelateResult, TypeRelation};
18+
use middle::ty::relate::{Relate, RelateOk, RelateResult, RelateResultTrait, TypeRelation};
1919

2020
/// Ensures `a` is made equal to `b`. Returns `a` on success.
2121
pub struct Equate<'a, 'tcx: 'a> {
@@ -47,30 +47,27 @@ impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {
4747
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
4848
debug!("{}.tys({:?}, {:?})", self.tag(),
4949
a, b);
50-
if a == b { return Ok(a); }
50+
if a == b { return Ok(RelateOk::from(a)); }
5151

5252
let infcx = self.fields.infcx;
5353
let a = infcx.type_variables.borrow().replace_if_possible(a);
5454
let b = infcx.type_variables.borrow().replace_if_possible(b);
5555
match (&a.sty, &b.sty) {
5656
(&ty::TyInfer(TyVar(a_id)), &ty::TyInfer(TyVar(b_id))) => {
5757
infcx.type_variables.borrow_mut().relate_vars(a_id, EqTo, b_id);
58-
Ok(a)
58+
Ok(RelateOk::from(a))
5959
}
6060

6161
(&ty::TyInfer(TyVar(a_id)), _) => {
62-
try!(self.fields.instantiate(b, EqTo, a_id));
63-
Ok(a)
62+
self.fields.instantiate(b, EqTo, a_id).map_value(|_| a)
6463
}
6564

6665
(_, &ty::TyInfer(TyVar(b_id))) => {
67-
try!(self.fields.instantiate(a, EqTo, b_id));
68-
Ok(a)
66+
self.fields.instantiate(a, EqTo, b_id).map_value(|_| a)
6967
}
7068

7169
_ => {
72-
try!(combine::super_combine_tys(self.fields.infcx, self, a, b));
73-
Ok(a)
70+
combine::super_combine_tys(self.fields.infcx, self, a, b).map_value(|_| a)
7471
}
7572
}
7673
}
@@ -82,14 +79,14 @@ impl<'a, 'tcx> TypeRelation<'a,'tcx> for Equate<'a, 'tcx> {
8279
b);
8380
let origin = Subtype(self.fields.trace.clone());
8481
self.fields.infcx.region_vars.make_eqregion(origin, a, b);
85-
Ok(a)
82+
Ok(RelateOk::from(a))
8683
}
8784

8885
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
8986
-> RelateResult<'tcx, ty::Binder<T>>
9087
where T: Relate<'a, 'tcx>
9188
{
92-
try!(self.fields.higher_ranked_sub(a, b));
93-
self.fields.higher_ranked_sub(b, a)
89+
self.fields.higher_ranked_sub(a, b)
90+
.and_then_with(|_| self.fields.higher_ranked_sub(b, a))
9491
}
9592
}

src/librustc/middle/infer/glb.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use super::lattice::{self, LatticeDir};
1515
use super::Subtype;
1616

1717
use middle::ty::{self, Ty};
18-
use middle::ty::relate::{Relate, RelateResult, TypeRelation};
18+
use middle::ty::relate::{Relate, RelateOk, RelateResult, RelateResultTrait, TypeRelation};
1919

2020
/// "Greatest lower bound" (common subtype)
2121
pub struct Glb<'a, 'tcx: 'a> {
@@ -60,7 +60,7 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Glb<'a, 'tcx> {
6060
b);
6161

6262
let origin = Subtype(self.fields.trace.clone());
63-
Ok(self.fields.infcx.region_vars.glb_regions(origin, a, b))
63+
Ok(RelateOk::from(self.fields.infcx.region_vars.glb_regions(origin, a, b)))
6464
}
6565

6666
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
@@ -78,8 +78,8 @@ impl<'a, 'tcx> LatticeDir<'a,'tcx> for Glb<'a, 'tcx> {
7878

7979
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
8080
let mut sub = self.fields.sub();
81-
try!(sub.relate(&v, &a));
82-
try!(sub.relate(&v, &b));
83-
Ok(())
81+
sub.relate(&v, &a)
82+
.and_then_with(|_| sub.relate(&v, &b))
83+
.and_then_with(|_| Ok(RelateOk::from(())))
8484
}
8585
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use super::combine::CombineFields;
1616

1717
use middle::ty::{self, Binder, TypeFoldable};
1818
use middle::ty::error::TypeError;
19-
use middle::ty::relate::{Relate, RelateResult, TypeRelation};
19+
use middle::ty::relate::{Relate, RelateOk, RelateResult, RelateResultTrait, TypeRelation};
2020
use syntax::codemap::Span;
2121
use util::nodemap::{FnvHashMap, FnvHashSet};
2222

@@ -97,7 +97,7 @@ impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
9797
debug!("higher_ranked_sub: OK result={:?}",
9898
result);
9999

100-
Ok(ty::Binder(result))
100+
Ok(result).map_value(|r| ty::Binder(r))
101101
});
102102
}
103103

@@ -117,7 +117,7 @@ impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
117117
span, HigherRankedType, b);
118118

119119
// Collect constraints.
120-
let result0 =
120+
let RelateOk { value: result0, obligations } =
121121
try!(self.lub().relate(&a_with_fresh, &b_with_fresh));
122122
let result0 =
123123
self.infcx.resolve_type_vars_if_possible(&result0);
@@ -138,7 +138,7 @@ impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
138138
b,
139139
result1);
140140

141-
Ok(ty::Binder(result1))
141+
Ok(RelateOk { value: ty::Binder(result1), obligations: obligations })
142142
});
143143

144144
fn generalize_region(infcx: &InferCtxt,
@@ -211,7 +211,7 @@ impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
211211
let b_vars = var_ids(self, &b_map);
212212

213213
// Collect constraints.
214-
let result0 =
214+
let RelateOk { value: result0, obligations } =
215215
try!(self.glb().relate(&a_with_fresh, &b_with_fresh));
216216
let result0 =
217217
self.infcx.resolve_type_vars_if_possible(&result0);
@@ -234,7 +234,7 @@ impl<'a,'tcx> HigherRankedRelations<'a,'tcx> for CombineFields<'a,'tcx> {
234234
b,
235235
result1);
236236

237-
Ok(ty::Binder(result1))
237+
Ok(RelateOk { value: ty::Binder(result1), obligations: obligations })
238238
});
239239

240240
fn generalize_region(infcx: &InferCtxt,

src/librustc/middle/infer/lattice.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use super::InferCtxt;
3434

3535
use middle::ty::TyVar;
3636
use middle::ty::{self, Ty};
37-
use middle::ty::relate::{RelateResult, TypeRelation};
37+
use middle::ty::relate::{RelateOk, RelateResult, RelateResultTrait, TypeRelation};
3838

3939
pub trait LatticeDir<'f,'tcx> : TypeRelation<'f,'tcx> {
4040
fn infcx(&self) -> &'f InferCtxt<'f, 'tcx>;
@@ -56,7 +56,7 @@ pub fn super_lattice_tys<'a,'tcx,L:LatticeDir<'a,'tcx>>(this: &mut L,
5656
b);
5757

5858
if a == b {
59-
return Ok(a);
59+
return Ok(RelateOk::from(a));
6060
}
6161

6262
let infcx = this.infcx();
@@ -66,15 +66,13 @@ pub fn super_lattice_tys<'a,'tcx,L:LatticeDir<'a,'tcx>>(this: &mut L,
6666
(&ty::TyInfer(TyVar(..)), &ty::TyInfer(TyVar(..)))
6767
if infcx.type_var_diverges(a) && infcx.type_var_diverges(b) => {
6868
let v = infcx.next_diverging_ty_var();
69-
try!(this.relate_bound(v, a, b));
70-
Ok(v)
69+
this.relate_bound(v, a, b).map_value(|_| v)
7170
}
7271

7372
(&ty::TyInfer(TyVar(..)), _) |
7473
(_, &ty::TyInfer(TyVar(..))) => {
7574
let v = infcx.next_ty_var();
76-
try!(this.relate_bound(v, a, b));
77-
Ok(v)
75+
this.relate_bound(v, a, b).map_value(|_| v)
7876
}
7977

8078
_ => {

src/librustc/middle/infer/lub.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use super::lattice::{self, LatticeDir};
1515
use super::Subtype;
1616

1717
use middle::ty::{self, Ty};
18-
use middle::ty::relate::{Relate, RelateResult, TypeRelation};
18+
use middle::ty::relate::{Relate, RelateOk, RelateResult, RelateResultTrait, TypeRelation};
1919

2020
/// "Least upper bound" (common supertype)
2121
pub struct Lub<'a, 'tcx: 'a> {
@@ -60,7 +60,7 @@ impl<'a, 'tcx> TypeRelation<'a, 'tcx> for Lub<'a, 'tcx> {
6060
b);
6161

6262
let origin = Subtype(self.fields.trace.clone());
63-
Ok(self.fields.infcx.region_vars.lub_regions(origin, a, b))
63+
Ok(RelateOk::from(self.fields.infcx.region_vars.lub_regions(origin, a, b)))
6464
}
6565

6666
fn binders<T>(&mut self, a: &ty::Binder<T>, b: &ty::Binder<T>)
@@ -78,8 +78,8 @@ impl<'a, 'tcx> LatticeDir<'a,'tcx> for Lub<'a, 'tcx> {
7878

7979
fn relate_bound(&self, v: Ty<'tcx>, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, ()> {
8080
let mut sub = self.fields.sub();
81-
try!(sub.relate(&a, &v));
82-
try!(sub.relate(&b, &v));
83-
Ok(())
81+
sub.relate(&a, &v)
82+
.and_then_with(|_| sub.relate(&b, &v))
83+
.and_then_with(|_| Ok(RelateOk::from(())))
8484
}
8585
}

0 commit comments

Comments
 (0)