Skip to content

Commit 9d01f08

Browse files
Plumb inference obligations through librustc_typeck
1 parent e09d1be commit 9d01f08

File tree

8 files changed

+107
-52
lines changed

8 files changed

+107
-52
lines changed

src/librustc/middle/infer/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
385385
a_is_expected: bool,
386386
a: Ty<'tcx>,
387387
b: Ty<'tcx>)
388-
-> RelateResult<'tcx, Ty<'tcx>>
388+
-> RelateOk<'tcx, Ty<'tcx>>
389389
{
390390
debug!("common_supertype({:?}, {:?})",
391391
a, b);
@@ -397,10 +397,10 @@ pub fn common_supertype<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
397397

398398
let result = cx.commit_if_ok(|_| cx.lub(a_is_expected, trace.clone()).relate(&a, &b));
399399
match result {
400-
Ok(t) => Ok(t),
400+
Ok(t) => t,
401401
Err(ref err) => {
402402
cx.report_and_explain_type_error(trace, err);
403-
Ok(RelateOk::from(cx.tcx.types.err))
403+
RelateOk::from(cx.tcx.types.err)
404404
}
405405
}
406406
}

src/librustc_typeck/check/_match.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -538,13 +538,7 @@ pub fn check_match<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
538538
),
539539
};
540540

541-
infer::common_supertype(
542-
fcx.infcx(),
543-
origin,
544-
true,
545-
expected,
546-
found,
547-
)
541+
fcx.common_supertype(origin, true, expected, found)
548542
}
549543
});
550544

src/librustc_typeck/check/coercion.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ use middle::ty::adjustment::{AdjustUnsafeFnPointer};
7171
use middle::ty::{self, LvaluePreference, TypeAndMut, Ty};
7272
use middle::ty::fold::TypeFoldable;
7373
use middle::ty::error::TypeError;
74-
use middle::ty::relate::RelateResult;
74+
use middle::ty::relate::{RelateOk};
7575
use util::common::indent;
7676

7777
use std::cell::RefCell;
@@ -84,16 +84,21 @@ struct Coerce<'a, 'tcx: 'a> {
8484
unsizing_obligations: RefCell<Vec<traits::PredicateObligation<'tcx>>>,
8585
}
8686

87-
type CoerceResult<'tcx> = RelateResult<'tcx, Option<AutoAdjustment<'tcx>>>;
87+
type CoerceResult<'tcx> = Result<Option<AutoAdjustment<'tcx>>, TypeError<'tcx>>;
8888

8989
impl<'f, 'tcx> Coerce<'f, 'tcx> {
9090
fn tcx(&self) -> &ty::ctxt<'tcx> {
9191
self.fcx.tcx()
9292
}
9393

9494
fn subtype(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
95-
try!(self.fcx.infcx().sub_types(false, self.origin.clone(), a, b));
96-
Ok(None) // No coercion required.
95+
self.fcx.infcx().sub_types(false, self.origin.clone(), a, b)
96+
.map(|RelateOk { obligations, .. }| {
97+
for obligation in obligations {
98+
self.fcx.register_predicate(obligation);
99+
}
100+
None
101+
})
97102
}
98103

99104
fn unpack_actual_value<T, F>(&self, a: Ty<'tcx>, f: F) -> T where
@@ -206,13 +211,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
206211
}
207212
let ty = self.tcx().mk_ref(r_borrow,
208213
TypeAndMut {ty: inner_ty, mutbl: mutbl_b});
209-
if let Err(err) = self.subtype(ty, b) {
210-
if first_error.is_none() {
211-
first_error = Some(err);
214+
match self.subtype(ty, b) {
215+
Err(err) => {
216+
if first_error.is_none() {
217+
first_error = Some(err);
218+
}
219+
None
220+
},
221+
Ok(_) => {
222+
Some(())
212223
}
213-
None
214-
} else {
215-
Some(())
216224
}
217225
});
218226

@@ -437,7 +445,7 @@ pub fn mk_assignty<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
437445
expr: &hir::Expr,
438446
a: Ty<'tcx>,
439447
b: Ty<'tcx>)
440-
-> RelateResult<'tcx, ()> {
448+
-> Result<(), TypeError<'tcx>> {
441449
debug!("mk_assignty({:?} -> {:?})", a, b);
442450
let mut unsizing_obligations = vec![];
443451
let adjustment = try!(indent(|| {

src/librustc_typeck/check/compare_method.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use middle::free_region::FreeRegionMap;
1212
use middle::infer::{self, TypeOrigin};
1313
use middle::traits;
1414
use middle::ty::{self};
15+
use middle::ty::relate::RelateOk;
1516
use middle::subst::{self, Subst, Substs, VecPerParamSpace};
1617

1718
use syntax::ast;
@@ -323,13 +324,20 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
323324
debug!("compare_impl_method: trait_fty={:?}",
324325
trait_fty);
325326

326-
try!(infer::mk_subty(&infcx, false, origin, impl_fty, trait_fty));
327+
let RelateOk { obligations, .. } =
328+
try!(infer::mk_subty(&infcx, false, origin, impl_fty, trait_fty));
327329

330+
for obligation in obligations {
331+
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
332+
}
328333
infcx.leak_check(&skol_map, snapshot)
329334
});
330335

331336
match err {
332-
Ok(()) => { }
337+
Ok(RelateOk { obligations, .. }) =>
338+
for obligation in obligations {
339+
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
340+
},
333341
Err(terr) => {
334342
debug!("checking trait method for compatibility: impl ty {:?}, trait ty {:?}",
335343
impl_fty,
@@ -475,7 +483,10 @@ pub fn compare_const_impl<'tcx>(tcx: &ty::ctxt<'tcx>,
475483
});
476484

477485
match err {
478-
Ok(()) => { }
486+
Ok(RelateOk { obligations, .. }) =>
487+
for obligation in obligations {
488+
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
489+
},
479490
Err(terr) => {
480491
debug!("checking associated const for compatibility: impl ty {:?}, trait ty {:?}",
481492
impl_ty,

src/librustc_typeck/check/demand.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
use check::{coercion, FnCtxt};
1313
use middle::ty::{self, Ty};
14-
use middle::infer::{self, TypeOrigin};
14+
use middle::infer::{TypeOrigin};
1515

1616
use std::result::Result::{Err, Ok};
1717
use syntax::codemap::Span;
@@ -35,8 +35,8 @@ pub fn suptype_with_fn<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
3535
F: FnOnce(Span, Ty<'tcx>, Ty<'tcx>, &ty::error::TypeError<'tcx>),
3636
{
3737
// n.b.: order of actual, expected is reversed
38-
match infer::mk_subty(fcx.infcx(), b_is_expected, TypeOrigin::Misc(sp),
39-
ty_b, ty_a) {
38+
match fcx.mk_subty(b_is_expected, TypeOrigin::Misc(sp),
39+
ty_b, ty_a) {
4040
Ok(()) => { /* ok */ }
4141
Err(ref err) => {
4242
handle_err(sp, ty_a, ty_b, err);
@@ -46,7 +46,7 @@ pub fn suptype_with_fn<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
4646

4747
pub fn eqtype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
4848
expected: Ty<'tcx>, actual: Ty<'tcx>) {
49-
match infer::mk_eqty(fcx.infcx(), false, TypeOrigin::Misc(sp), actual, expected) {
49+
match fcx.mk_eqty(false, TypeOrigin::Misc(sp), actual, expected) {
5050
Ok(()) => { /* ok */ }
5151
Err(ref err) => { fcx.report_mismatched_types(sp, expected, actual, err); }
5252
}

src/librustc_typeck/check/method/probe.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ use middle::subst;
2020
use middle::subst::Subst;
2121
use middle::traits;
2222
use middle::ty::{self, NoPreference, Ty, ToPolyTraitRef, TraitRef, TypeFoldable};
23-
use middle::infer;
23+
use middle::ty::error::{TypeError};
2424
use middle::infer::{InferCtxt, TypeOrigin};
25+
use middle::ty::relate::RelateOk;
2526
use syntax::ast;
2627
use syntax::codemap::{Span, DUMMY_SP};
2728
use rustc_front::hir;
@@ -1133,8 +1134,14 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
11331134
///////////////////////////////////////////////////////////////////////////
11341135
// MISCELLANY
11351136

1136-
fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> infer::UnitResult<'tcx> {
1137+
fn make_sub_ty(&self, sub: Ty<'tcx>, sup: Ty<'tcx>) -> Result<(), TypeError<'tcx>> {
11371138
self.infcx().sub_types(false, TypeOrigin::Misc(DUMMY_SP), sub, sup)
1139+
.map(|RelateOk { value, obligations }| {
1140+
for obligation in obligations {
1141+
self.fcx.register_predicate(obligation);
1142+
}
1143+
value
1144+
})
11381145
}
11391146

11401147
fn has_applicable_self(&self, item: &ty::ImplOrTraitItem) -> bool {

src/librustc_typeck/check/mod.rs

+50-21
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ use middle::ty::{MethodCall, MethodCallee};
102102
use middle::ty::adjustment;
103103
use middle::ty::error::TypeError;
104104
use middle::ty::fold::{TypeFolder, TypeFoldable};
105+
use middle::ty::relate::RelateOk;
105106
use middle::ty::util::Representability;
106107
use require_c_abi_if_variadic;
107108
use rscope::{ElisionFailureInfo, RegionScope};
@@ -1206,6 +1207,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12061207
&self.inh.infcx
12071208
}
12081209

1210+
pub fn fulfillment_cx(&self) -> &RefCell<traits::FulfillmentContext<'tcx>> {
1211+
&self.inh.fulfillment_cx
1212+
}
1213+
12091214
pub fn param_env(&self) -> &ty::ParameterEnvironment<'a,'tcx> {
12101215
&self.inh.infcx.parameter_environment
12111216
}
@@ -1248,6 +1253,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12481253
ty
12491254
}
12501255

1256+
pub fn common_supertype(&self,
1257+
origin: TypeOrigin,
1258+
a_is_expected: bool,
1259+
a: Ty<'tcx>,
1260+
b: Ty<'tcx>)
1261+
-> Ty<'tcx>
1262+
{
1263+
let RelateOk { value, obligations } = infer::common_supertype(
1264+
self.infcx(), origin, a_is_expected, a, b);
1265+
for obligation in obligations {
1266+
self.register_predicate(obligation);
1267+
}
1268+
value
1269+
}
1270+
12511271
fn record_deferred_call_resolution(&self,
12521272
closure_def_id: DefId,
12531273
r: DeferredCallResolutionHandler<'tcx>) {
@@ -1593,6 +1613,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15931613
sup: Ty<'tcx>)
15941614
-> Result<(), TypeError<'tcx>> {
15951615
infer::mk_subty(self.infcx(), a_is_expected, origin, sub, sup)
1616+
.map(|RelateOk { value, obligations }| {
1617+
for obligation in obligations {
1618+
self.register_predicate(obligation);
1619+
}
1620+
value
1621+
})
15961622
}
15971623

15981624
pub fn mk_eqty(&self,
@@ -1602,6 +1628,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16021628
sup: Ty<'tcx>)
16031629
-> Result<(), TypeError<'tcx>> {
16041630
infer::mk_eqty(self.infcx(), a_is_expected, origin, sub, sup)
1631+
.map(|RelateOk { value, obligations }| {
1632+
for obligation in obligations {
1633+
self.register_predicate(obligation);
1634+
}
1635+
value
1636+
})
16051637
}
16061638

16071639
pub fn mk_subr(&self,
@@ -1885,9 +1917,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18851917
Neither => {
18861918
if let Some(default) = default_map.get(ty) {
18871919
let default = default.clone();
1888-
match infer::mk_eqty(self.infcx(), false,
1889-
TypeOrigin::Misc(default.origin_span),
1890-
ty, default.ty) {
1920+
match self.mk_eqty(false,
1921+
TypeOrigin::Misc(default.origin_span),
1922+
ty, default.ty) {
18911923
Ok(()) => {}
18921924
Err(_) => {
18931925
conflicts.push((*ty, default));
@@ -1978,9 +2010,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19782010
Neither => {
19792011
if let Some(default) = default_map.get(ty) {
19802012
let default = default.clone();
1981-
match infer::mk_eqty(self.infcx(), false,
1982-
TypeOrigin::Misc(default.origin_span),
1983-
ty, default.ty) {
2013+
match self.mk_eqty(false,
2014+
TypeOrigin::Misc(default.origin_span),
2015+
ty, default.ty) {
19842016
Ok(()) => {}
19852017
Err(_) => {
19862018
result = Some(default);
@@ -2880,18 +2912,16 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
28802912
Some(ref else_expr) => {
28812913
check_expr_with_expectation(fcx, &else_expr, expected);
28822914
let else_ty = fcx.expr_ty(&else_expr);
2883-
infer::common_supertype(fcx.infcx(),
2884-
TypeOrigin::IfExpression(sp),
2885-
true,
2886-
then_ty,
2887-
else_ty)
2915+
fcx.common_supertype(TypeOrigin::IfExpression(sp),
2916+
true,
2917+
then_ty,
2918+
else_ty)
28882919
}
28892920
None => {
2890-
infer::common_supertype(fcx.infcx(),
2891-
TypeOrigin::IfExpressionWithNoElse(sp),
2892-
false,
2893-
then_ty,
2894-
fcx.tcx().mk_nil())
2921+
fcx.common_supertype(TypeOrigin::IfExpressionWithNoElse(sp),
2922+
false,
2923+
then_ty,
2924+
fcx.tcx().mk_nil())
28952925
}
28962926
};
28972927

@@ -3685,11 +3715,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
36853715
Some(fcx.tcx().types.err)
36863716
}
36873717
(Some(t_start), Some(t_end)) => {
3688-
Some(infer::common_supertype(fcx.infcx(),
3689-
TypeOrigin::RangeExpression(expr.span),
3690-
true,
3691-
t_start,
3692-
t_end))
3718+
Some(fcx.common_supertype(TypeOrigin::RangeExpression(expr.span),
3719+
true,
3720+
t_start,
3721+
t_end))
36933722
}
36943723
_ => None
36953724
};

src/librustc_typeck/check/regionck.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ use middle::region::{self, CodeExtent};
9292
use middle::subst::Substs;
9393
use middle::traits;
9494
use middle::ty::{self, Ty, MethodCall, TypeFoldable};
95+
use middle::ty::relate::RelateOk;
9596
use middle::infer::{self, GenericKind, InferCtxt, SubregionOrigin, TypeOrigin, VerifyBound};
9697
use middle::pat_util;
9798
use middle::ty::adjustment;
@@ -1846,7 +1847,12 @@ fn declared_projection_bounds_from_trait<'a,'tcx>(rcx: &Rcx<'a, 'tcx>,
18461847

18471848
// check whether this predicate applies to our current projection
18481849
match infer::mk_eqty(infcx, false, TypeOrigin::Misc(span), ty, outlives.0) {
1849-
Ok(()) => { Ok(outlives.1) }
1850+
Ok(RelateOk { obligations, .. }) => {
1851+
for obligation in obligations {
1852+
fcx.register_predicate(obligation);
1853+
}
1854+
Ok(outlives.1)
1855+
}
18501856
Err(_) => { Err(()) }
18511857
}
18521858
});

0 commit comments

Comments
 (0)