Skip to content

Commit 93e1097

Browse files
committed
propagate other obligations that were left out
cc #32730 -- I left exactly one instance where I wasn't sure of the right behavior.
1 parent aa6c2b1 commit 93e1097

File tree

7 files changed

+40
-22
lines changed

7 files changed

+40
-22
lines changed

src/librustc/infer/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1597,9 +1597,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
15971597
// generic so we don't have to do anything quite this
15981598
// terrible.
15991599
let trace = TypeTrace::dummy(self.tcx);
1600-
self.equate(true, trace, a, b).map(|InferOk { obligations, .. }| {
1601-
// FIXME(#32730) propagate obligations
1602-
assert!(obligations.is_empty());
1600+
self.equate(true, trace, a, b).map(|InferOk { obligations: _, .. }| {
1601+
// We can intentionally ignore obligations here, since
1602+
// this is part of a simple test for general
1603+
// "equatability". However, it's not entirely clear
1604+
// that we *ought* to be, perhaps a better thing would
1605+
// be to use a mini-fulfillment context or something
1606+
// like that.
16031607
})
16041608
})
16051609
}

src/librustc/traits/fulfill.rs

+10
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,16 @@ impl<'a, 'gcx, 'tcx> FulfillmentContext<'tcx> {
184184
});
185185
}
186186

187+
pub fn register_predicate_obligations(&mut self,
188+
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
189+
obligations: Vec<PredicateObligation<'tcx>>)
190+
{
191+
for obligation in obligations {
192+
self.register_predicate_obligation(infcx, obligation);
193+
}
194+
}
195+
196+
187197
pub fn region_obligations(&self,
188198
body_id: ast::NodeId)
189199
-> &[RegionObligation<'tcx>]

src/librustc/traits/specialize/mod.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
218218
-> Result<&'tcx Substs<'tcx>, ()> {
219219
let selcx = &mut SelectionContext::new(&infcx);
220220
let target_substs = infcx.fresh_substs_for_item(DUMMY_SP, target_impl);
221-
let (target_trait_ref, obligations) = impl_trait_ref_and_oblig(selcx,
221+
let (target_trait_ref, mut obligations) = impl_trait_ref_and_oblig(selcx,
222222
target_impl,
223223
target_substs);
224224

@@ -227,9 +227,8 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
227227
&ObligationCause::dummy(),
228228
source_trait_ref,
229229
target_trait_ref) {
230-
Ok(InferOk { obligations, .. }) => {
231-
// FIXME(#32730) propagate obligations
232-
assert!(obligations.is_empty())
230+
Ok(InferOk { obligations: o, .. }) => {
231+
obligations.extend(o);
233232
}
234233
Err(_) => {
235234
debug!("fulfill_implication: {:?} does not unify with {:?}",

src/librustc_driver/test.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
376376
pub fn check_sub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) {
377377
match self.sub(t1, t2) {
378378
Ok(InferOk { obligations, .. }) => {
379-
// FIXME(#32730) once obligations are being propagated, assert the right thing.
379+
// None of these tests should require nested obligations:
380380
assert!(obligations.is_empty());
381381
}
382382
Err(ref e) => {
@@ -400,7 +400,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
400400
pub fn check_lub(&self, t1: Ty<'tcx>, t2: Ty<'tcx>, t_lub: Ty<'tcx>) {
401401
match self.lub(t1, t2) {
402402
Ok(InferOk { obligations, value: t }) => {
403-
// FIXME(#32730) once obligations are being propagated, assert the right thing.
403+
// None of these tests should require nested obligations:
404404
assert!(obligations.is_empty());
405405

406406
self.assert_eq(t, t_lub);
@@ -415,7 +415,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
415415
match self.glb(t1, t2) {
416416
Err(e) => panic!("unexpected error computing LUB: {:?}", e),
417417
Ok(InferOk { obligations, value: t }) => {
418-
// FIXME(#32730) once obligations are being propagated, assert the right thing.
418+
// None of these tests should require nested obligations:
419419
assert!(obligations.is_empty());
420420

421421
self.assert_eq(t, t_glb);

src/librustc_typeck/check/compare_method.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,9 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
294294
debug!("compare_impl_method: trait_fty={:?}", trait_fty);
295295

296296
let sub_result = infcx.sub_types(false, &cause, impl_fty, trait_fty)
297-
.map(|InferOk { obligations, .. }| {
298-
// FIXME(#32730) propagate obligations
299-
assert!(obligations.is_empty());
300-
});
297+
.map(|InferOk { obligations, .. }| {
298+
inh.register_predicates(obligations);
299+
});
301300

302301
if let Err(terr) = sub_result {
303302
debug!("sub_types failed: impl ty {:?}, trait ty {:?}",

src/librustc_typeck/check/dropck.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
8282
// check that the impl type can be made to match the trait type.
8383

8484
let impl_param_env = ty::ParameterEnvironment::for_item(tcx, self_type_node_id);
85-
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|infcx| {
85+
tcx.infer_ctxt(impl_param_env, Reveal::UserFacing).enter(|ref infcx| {
8686
let tcx = infcx.tcx;
8787
let mut fulfillment_cx = traits::FulfillmentContext::new();
8888

@@ -97,8 +97,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
9797
let cause = &ObligationCause::misc(drop_impl_span, drop_impl_node_id);
9898
match infcx.eq_types(true, cause, named_type, fresh_impl_self_ty) {
9999
Ok(InferOk { obligations, .. }) => {
100-
// FIXME(#32730) propagate obligations
101-
assert!(obligations.is_empty());
100+
fulfillment_cx.register_predicate_obligations(infcx, obligations);
102101
}
103102
Err(_) => {
104103
let item_span = tcx.hir.span(self_type_node_id);

src/librustc_typeck/lib.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ use rustc::infer::InferOk;
109109
use rustc::ty::subst::Substs;
110110
use rustc::ty::{self, Ty, TyCtxt};
111111
use rustc::ty::maps::Providers;
112-
use rustc::traits::{ObligationCause, ObligationCauseCode, Reveal};
112+
use rustc::traits::{FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
113113
use session::config;
114114
use util::common::time;
115115

@@ -153,15 +153,22 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
153153
expected: Ty<'tcx>,
154154
actual: Ty<'tcx>)
155155
-> bool {
156-
tcx.infer_ctxt((), Reveal::UserFacing).enter(|infcx| {
156+
tcx.infer_ctxt((), Reveal::UserFacing).enter(|ref infcx| {
157+
let mut fulfill_cx = FulfillmentContext::new();
157158
match infcx.eq_types(false, &cause, expected, actual) {
158159
Ok(InferOk { obligations, .. }) => {
159-
// FIXME(#32730) propagate obligations
160-
assert!(obligations.is_empty());
161-
true
160+
fulfill_cx.register_predicate_obligations(infcx, obligations);
162161
}
163162
Err(err) => {
164163
infcx.report_mismatched_types(cause, expected, actual, err).emit();
164+
return false;
165+
}
166+
}
167+
168+
match fulfill_cx.select_all_or_error(infcx) {
169+
Ok(()) => true,
170+
Err(errors) => {
171+
infcx.report_fulfillment_errors(&errors);
165172
false
166173
}
167174
}

0 commit comments

Comments
 (0)