do not allow inference in pred_known_to_hold_modulo_regions
This commit is contained in:
parent
dbbb42442c
commit
c06e61151c
4 changed files with 37 additions and 22 deletions
|
@ -142,35 +142,36 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
|
|||
fn pred_known_to_hold_modulo_regions<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
pred: impl ToPredicate<'tcx> + TypeVisitable<TyCtxt<'tcx>>,
|
||||
pred: impl ToPredicate<'tcx>,
|
||||
) -> bool {
|
||||
let has_non_region_infer = pred.has_non_region_infer();
|
||||
let obligation = Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, pred);
|
||||
|
||||
let result = infcx.evaluate_obligation_no_overflow(&obligation);
|
||||
debug!(?result);
|
||||
|
||||
if result.must_apply_modulo_regions() && !has_non_region_infer {
|
||||
if result.must_apply_modulo_regions() {
|
||||
true
|
||||
} else if result.may_apply() {
|
||||
// Because of inference "guessing", selection can sometimes claim
|
||||
// to succeed while the success requires a guess. To ensure
|
||||
// this function's result remains infallible, we must confirm
|
||||
// that guess. While imperfect, I believe this is sound.
|
||||
// Sometimes obligations are ambiguous because the recursive evaluator
|
||||
// is not smart enough, so we fall back to fulfillment when we're not certain
|
||||
// that an obligation holds or not. Even still, we must make sure that
|
||||
// the we do no inference in the process of checking this obligation.
|
||||
let goal = infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
|
||||
infcx.probe(|_| {
|
||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
||||
ocx.register_obligation(obligation);
|
||||
|
||||
// The handling of regions in this area of the code is terrible,
|
||||
// see issue #29149. We should be able to improve on this with
|
||||
// NLL.
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
ocx.register_obligation(obligation);
|
||||
let errors = ocx.select_all_or_error();
|
||||
match errors.as_slice() {
|
||||
[] => true,
|
||||
errors => {
|
||||
debug!(?errors);
|
||||
false
|
||||
let errors = ocx.select_all_or_error();
|
||||
match errors.as_slice() {
|
||||
// Only known to hold if we did no inference.
|
||||
[] => infcx.shallow_resolve(goal) == goal,
|
||||
|
||||
errors => {
|
||||
debug!(?errors);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue