Skip to content

Commit 4e4bdea

Browse files
committed
propagate sub-obligations better
The most interesting place is the hinting mechanism; once we start having subtyping obligations, it's important to see those through.
1 parent 58609ef commit 4e4bdea

File tree

2 files changed

+29
-12
lines changed

2 files changed

+29
-12
lines changed

src/librustc_typeck/check/method/probe.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,19 +1149,16 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
11491149

11501150
self.probe(|_| {
11511151
// First check that the self type can be related.
1152-
match self.sub_types(false,
1153-
&ObligationCause::dummy(),
1154-
self_ty,
1155-
probe.xform_self_ty) {
1156-
Ok(InferOk { obligations, value: () }) => {
1157-
// FIXME(#32730) propagate obligations
1158-
assert!(obligations.is_empty())
1159-
}
1152+
let sub_obligations = match self.sub_types(false,
1153+
&ObligationCause::dummy(),
1154+
self_ty,
1155+
probe.xform_self_ty) {
1156+
Ok(InferOk { obligations, value: () }) => obligations,
11601157
Err(_) => {
11611158
debug!("--> cannot relate self-types");
11621159
return false;
11631160
}
1164-
}
1161+
};
11651162

11661163
// If so, impls may carry other conditions (e.g., where
11671164
// clauses) that must be considered. Make sure that those
@@ -1200,6 +1197,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
12001197
// Evaluate those obligations to see if they might possibly hold.
12011198
let mut all_true = true;
12021199
for o in obligations.iter()
1200+
.chain(sub_obligations.iter())
12031201
.chain(norm_obligations.iter())
12041202
.chain(ref_obligations.iter()) {
12051203
if !selcx.evaluate_obligation(o) {

src/librustc_typeck/check/mod.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ use rustc_back::slice::ref_slice;
9090
use rustc::infer::{self, InferCtxt, InferOk, RegionVariableOrigin};
9191
use rustc::infer::type_variable::{TypeVariableOrigin};
9292
use rustc::ty::subst::{Kind, Subst, Substs};
93-
use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
93+
use rustc::traits::{self, FulfillmentContext, ObligationCause, ObligationCauseCode, Reveal};
9494
use rustc::ty::{ParamTy, ParameterEnvironment};
9595
use rustc::ty::{LvaluePreference, NoPreference, PreferMutLvalue};
9696
use rustc::ty::{self, Ty, TyCtxt, Visibility};
@@ -2552,11 +2552,30 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25522552
// No argument expectations are produced if unification fails.
25532553
let origin = self.misc(call_span);
25542554
let ures = self.sub_types(false, &origin, formal_ret, ret_ty);
2555+
25552556
// FIXME(#15760) can't use try! here, FromError doesn't default
25562557
// to identity so the resulting type is not constrained.
25572558
match ures {
2558-
Ok(ok) => self.register_infer_ok_obligations(ok),
2559-
Err(e) => return Err(e),
2559+
Ok(ok) => {
2560+
// Process any obligations locally as much as
2561+
// we can. We don't care if some things turn
2562+
// out unconstrained or ambiguous, as we're
2563+
// just trying to get hints here.
2564+
let result = self.save_and_restore_obligations_in_snapshot_flag(|_| {
2565+
let mut fulfill = FulfillmentContext::new();
2566+
let ok = ok; // FIXME(#30046)
2567+
for obligation in ok.obligations {
2568+
fulfill.register_predicate_obligation(self, obligation);
2569+
}
2570+
fulfill.select_where_possible(self)
2571+
});
2572+
2573+
match result {
2574+
Ok(()) => { }
2575+
Err(_) => return Err(()),
2576+
}
2577+
}
2578+
Err(_) => return Err(()),
25602579
}
25612580

25622581
// Record all the argument types, with the substitutions

0 commit comments

Comments
 (0)