rename select_where_possible and select_all_or_error
This commit is contained in:
@@ -420,7 +420,7 @@ fn try_extract_error_from_fulfill_cx<'a, 'tcx>(
|
||||
// We generally shouldn't have errors here because the query was
|
||||
// already run, but there's no point using `span_delayed_bug`
|
||||
// when we're going to emit an error here anyway.
|
||||
let _errors = ocx.select_all_or_error();
|
||||
let _errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
let region_constraints = ocx.infcx.with_region_constraints(|r| r.clone());
|
||||
try_extract_error_from_region_constraints(
|
||||
ocx.infcx,
|
||||
|
||||
@@ -1313,7 +1313,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(self.infcx);
|
||||
let cause = ObligationCause::misc(expr.span, self.mir_def_id());
|
||||
ocx.register_bound(cause, self.infcx.param_env, ty, clone_trait);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if errors.iter().all(|error| {
|
||||
match error.obligation.predicate.as_clause().and_then(|c| c.as_trait_clause()) {
|
||||
Some(clause) => match clause.self_ty().skip_binder().kind() {
|
||||
@@ -1497,7 +1497,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
let cause = ObligationCause::misc(span, self.mir_def_id());
|
||||
|
||||
ocx.register_bound(cause, self.infcx.param_env, ty, def_id);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
|
||||
// Only emit suggestion if all required predicates are on generic
|
||||
let predicates: Result<Vec<_>, _> = errors
|
||||
|
||||
@@ -1134,7 +1134,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
Obligation::misc(tcx, span, self.mir_def_id(), self.infcx.param_env, pred)
|
||||
}));
|
||||
|
||||
if ocx.select_all_or_error().is_empty() && count > 0 {
|
||||
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 {
|
||||
diag.span_suggestion_verbose(
|
||||
tcx.hir_body(*body).value.peel_blocks().span.shrink_to_lo(),
|
||||
fluent::borrowck_dereference_suggestion,
|
||||
|
||||
@@ -657,7 +657,7 @@ impl<'tcx> LivenessContext<'_, '_, 'tcx> {
|
||||
let errors = match dropck_outlives::compute_dropck_outlives_with_errors(
|
||||
&ocx, op, span,
|
||||
) {
|
||||
Ok(_) => ocx.select_all_or_error(),
|
||||
Ok(_) => ocx.evaluate_obligations_error_on_ambiguity(),
|
||||
Err(e) => e,
|
||||
};
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ pub fn validate_trivial_unsize<'tcx>(
|
||||
) else {
|
||||
return false;
|
||||
};
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
return false;
|
||||
}
|
||||
infcx.leak_check(universe, None).is_ok()
|
||||
|
||||
@@ -415,7 +415,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||
)
|
||||
}));
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if errors.is_empty() {
|
||||
Some(ConstConditionsHold::Yes)
|
||||
} else {
|
||||
|
||||
@@ -119,7 +119,7 @@ impl Qualif for HasMutInterior {
|
||||
ty::TraitRef::new(cx.tcx, freeze_def_id, [ty::GenericArg::from(ty)]),
|
||||
);
|
||||
ocx.register_obligation(obligation);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
!errors.is_empty()
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||
},
|
||||
),
|
||||
));
|
||||
!ocx.select_all_or_error().is_empty()
|
||||
!ocx.evaluate_obligations_error_on_ambiguity().is_empty()
|
||||
}
|
||||
|
||||
fn is_structural_in_adt_value<'tcx>(cx: &ConstCx<'_, 'tcx>, adt: AdtDef<'tcx>) -> bool {
|
||||
|
||||
@@ -43,5 +43,5 @@ pub fn relate_types<'tcx>(
|
||||
Ok(()) => {}
|
||||
Err(_) => return false,
|
||||
};
|
||||
ocx.select_all_or_error().is_empty()
|
||||
ocx.evaluate_obligations_error_on_ambiguity().is_empty()
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
||||
// evaluate/fulfill mismatches, but that's not a reason for an ICE.
|
||||
return None;
|
||||
};
|
||||
let errors = ocx.select_where_possible();
|
||||
let errors = ocx.try_evaluate_obligations();
|
||||
if !errors.is_empty() {
|
||||
if self.infcx.next_trait_solver() {
|
||||
unreachable!();
|
||||
|
||||
@@ -235,7 +235,7 @@ fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>(
|
||||
// They can probably get removed with better treatment of the new `DropImpl`
|
||||
// obligation cause code, and perhaps some custom logic in `report_region_errors`.
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
let mut guar = None;
|
||||
let mut root_predicates = FxHashSet::default();
|
||||
|
||||
@@ -375,7 +375,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
let guar = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(guar);
|
||||
@@ -2028,7 +2028,7 @@ pub(super) fn check_coroutine_obligations(
|
||||
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, *predicate));
|
||||
}
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
debug!(?errors);
|
||||
if !errors.is_empty() {
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
@@ -2072,7 +2072,7 @@ pub(super) fn check_potentially_region_dependent_goals<'tcx>(
|
||||
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate));
|
||||
}
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
debug!(?errors);
|
||||
if errors.is_empty() { Ok(()) } else { Err(infcx.err_ctxt().report_fulfillment_errors(errors)) }
|
||||
}
|
||||
|
||||
@@ -363,7 +363,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(reported);
|
||||
@@ -669,7 +669,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// RPITs.
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
if let Err(guar) = try_report_async_mismatch(tcx, infcx, &errors, trait_m, impl_m, impl_sig)
|
||||
{
|
||||
@@ -1215,7 +1215,7 @@ fn check_region_late_boundedness<'tcx>(
|
||||
return None;
|
||||
};
|
||||
|
||||
let errors = ocx.select_where_possible();
|
||||
let errors = ocx.try_evaluate_obligations();
|
||||
if !errors.is_empty() {
|
||||
return None;
|
||||
}
|
||||
@@ -2106,7 +2106,7 @@ fn compare_const_predicate_entailment<'tcx>(
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
}
|
||||
@@ -2242,7 +2242,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(reported);
|
||||
@@ -2367,7 +2367,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
ocx.register_obligations(obligations);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(reported);
|
||||
|
||||
@@ -164,7 +164,7 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
|
||||
param_env,
|
||||
trait_m_sig.inputs_and_output,
|
||||
));
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
tcx.dcx().delayed_bug("encountered errors when checking RPITIT refinement (selection)");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
|
||||
let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
let norm_return_ty = ocx.normalize(&cause, param_env, return_ty);
|
||||
ocx.register_bound(cause, param_env, norm_return_ty, term_did);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
error = true;
|
||||
|
||||
@@ -660,7 +660,7 @@ pub fn check_function_signature<'tcx>(
|
||||
|
||||
match ocx.eq(&cause, param_env, expected_sig, actual_sig) {
|
||||
Ok(()) => {
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ where
|
||||
}
|
||||
f(&mut wfcx)?;
|
||||
|
||||
let errors = wfcx.select_all_or_error();
|
||||
let errors = wfcx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
return Err(infcx.err_ctxt().report_fulfillment_errors(errors));
|
||||
}
|
||||
@@ -1803,7 +1803,11 @@ fn receiver_is_valid<'tcx>(
|
||||
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
|
||||
let ocx = ObligationCtxt::new(wfcx.infcx);
|
||||
ocx.eq(&cause, wfcx.param_env, self_ty, receiver_ty)?;
|
||||
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
|
||||
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
}
|
||||
}) {
|
||||
return Ok(());
|
||||
}
|
||||
@@ -1838,7 +1842,11 @@ fn receiver_is_valid<'tcx>(
|
||||
if let Ok(()) = wfcx.infcx.commit_if_ok(|_| {
|
||||
let ocx = ObligationCtxt::new(wfcx.infcx);
|
||||
ocx.eq(&cause, wfcx.param_env, self_ty, potential_self_ty)?;
|
||||
if ocx.select_all_or_error().is_empty() { Ok(()) } else { Err(NoSolution) }
|
||||
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(NoSolution)
|
||||
}
|
||||
}) {
|
||||
wfcx.register_obligations(autoderef.into_obligations());
|
||||
return Ok(());
|
||||
|
||||
@@ -333,7 +333,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<()
|
||||
param_env,
|
||||
ty::TraitRef::new(tcx, trait_ref.def_id, [ty_a, ty_b]),
|
||||
));
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
if is_from_coerce_pointee_derive(tcx, span) {
|
||||
return Err(tcx.dcx().emit_err(errors::CoerceFieldValidity {
|
||||
@@ -558,7 +558,7 @@ pub(crate) fn coerce_unsized_info<'tcx>(
|
||||
ty::TraitRef::new(tcx, trait_def_id, [source, target]),
|
||||
);
|
||||
ocx.register_obligation(obligation);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
|
||||
if !errors.is_empty() {
|
||||
if is_from_coerce_pointee_derive(tcx, span) {
|
||||
|
||||
@@ -315,7 +315,7 @@ fn orphan_check<'tcx>(
|
||||
let ocx = traits::ObligationCtxt::new(&infcx);
|
||||
let ty = ocx.normalize(&cause, ty::ParamEnv::empty(), user_ty);
|
||||
let ty = infcx.resolve_vars_if_possible(ty);
|
||||
let errors = ocx.select_where_possible();
|
||||
let errors = ocx.try_evaluate_obligations();
|
||||
if !errors.is_empty() {
|
||||
return Ok(user_ty);
|
||||
}
|
||||
|
||||
@@ -1267,7 +1267,7 @@ pub fn suggest_impl_trait<'tcx>(
|
||||
Ty::new_projection_from_args(infcx.tcx, assoc_item_def_id, args),
|
||||
);
|
||||
// FIXME(compiler-errors): We may benefit from resolving regions here.
|
||||
if ocx.select_where_possible().is_empty()
|
||||
if ocx.try_evaluate_obligations().is_empty()
|
||||
&& let item_ty = infcx.resolve_vars_if_possible(item_ty)
|
||||
&& let Some(item_ty) = item_ty.make_suggestable(infcx.tcx, false, None)
|
||||
&& let Some(sugg) = formatter(
|
||||
|
||||
@@ -95,7 +95,7 @@ pub(super) fn diagnostic_hir_wf_check<'tcx>(
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(tcx_ty.into())),
|
||||
));
|
||||
|
||||
for error in ocx.select_all_or_error() {
|
||||
for error in ocx.evaluate_obligations_error_on_ambiguity() {
|
||||
debug!("Wf-check got error for {:?}: {:?}", ty, error);
|
||||
if error.obligation.predicate == self.predicate {
|
||||
// Save the cause from the greatest depth - this corresponds
|
||||
|
||||
@@ -183,7 +183,7 @@ fn get_impl_args(
|
||||
&ObligationCause::misc(impl1_span, impl1_def_id),
|
||||
);
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
let guar = ocx.infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(guar);
|
||||
|
||||
@@ -140,7 +140,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
Ok(InferOk { value, obligations }) if self.next_trait_solver() => {
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
ocx.register_obligations(obligations);
|
||||
if ocx.select_where_possible().is_empty() {
|
||||
if ocx.try_evaluate_obligations().is_empty() {
|
||||
Ok(InferOk { value, obligations: ocx.into_pending_obligations() })
|
||||
} else {
|
||||
Err(TypeError::Mismatch)
|
||||
@@ -677,7 +677,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
Some(ty::PredicateKind::AliasRelate(..)) => {
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
ocx.register_obligation(obligation);
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
return Err(TypeError::Mismatch);
|
||||
}
|
||||
coercion.obligations.extend(ocx.into_pending_obligations());
|
||||
@@ -1099,7 +1099,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return false;
|
||||
};
|
||||
ocx.register_obligations(ok.obligations);
|
||||
ocx.select_where_possible().is_empty()
|
||||
ocx.try_evaluate_obligations().is_empty()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1203,7 +1203,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if self.next_trait_solver() {
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
let value = ocx.lub(cause, self.param_env, prev_ty, new_ty)?;
|
||||
if ocx.select_where_possible().is_empty() {
|
||||
if ocx.try_evaluate_obligations().is_empty() {
|
||||
Ok(InferOk {
|
||||
value,
|
||||
obligations: ocx.into_pending_obligations(),
|
||||
@@ -1818,7 +1818,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||
))
|
||||
}),
|
||||
);
|
||||
ocx.select_where_possible().is_empty()
|
||||
ocx.try_evaluate_obligations().is_empty()
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -2017,7 +2017,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.fudge_inference_if_ok(|| {
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
ocx.sup(&self.misc(path_span), self.param_env, expected, adt_ty)?;
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
return Err(TypeError::Mismatch);
|
||||
}
|
||||
Ok(self.resolve_vars_if_possible(adt_ty))
|
||||
@@ -3663,7 +3663,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
),
|
||||
);
|
||||
|
||||
let true_errors = ocx.select_where_possible();
|
||||
let true_errors = ocx.try_evaluate_obligations();
|
||||
|
||||
// Do a leak check -- we can't really report a useful error here,
|
||||
// but it at least avoids an ICE when the error has to do with higher-ranked
|
||||
@@ -3671,7 +3671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.leak_check(outer_universe, Some(snapshot))?;
|
||||
|
||||
// Bail if we have ambiguity errors, which we can't report in a useful way.
|
||||
let ambiguity_errors = ocx.select_all_or_error();
|
||||
let ambiguity_errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if true_errors.is_empty() && !ambiguity_errors.is_empty() {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
@@ -495,7 +495,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
|
||||
.expect("expected diverging var to be unconstrained");
|
||||
}
|
||||
|
||||
ocx.select_where_possible()
|
||||
ocx.try_evaluate_obligations()
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -654,7 +654,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
|
||||
) {
|
||||
let mut result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
|
||||
let mut result = self.fulfillment_cx.borrow_mut().try_evaluate_obligations(self);
|
||||
if !result.is_empty() {
|
||||
mutate_fulfillment_errors(&mut result);
|
||||
self.adjust_fulfillment_errors_for_expr_obligation(&mut result);
|
||||
|
||||
@@ -255,7 +255,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// No argument expectations are produced if unification fails.
|
||||
let origin = self.misc(call_span);
|
||||
ocx.sup(&origin, self.param_env, expected_output, formal_output)?;
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
return Err(TypeError::Mismatch);
|
||||
}
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
let normalized_fn_sig =
|
||||
ocx.normalize(&ObligationCause::dummy(), self.param_env, fn_sig);
|
||||
if ocx.select_all_or_error().is_empty() {
|
||||
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
let normalized_fn_sig = self.resolve_vars_if_possible(normalized_fn_sig);
|
||||
if !normalized_fn_sig.has_infer() {
|
||||
return normalized_fn_sig;
|
||||
@@ -347,7 +347,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
|
||||
);
|
||||
ocx.register_obligations(impl_obligations);
|
||||
|
||||
let mut errors = ocx.select_where_possible();
|
||||
let mut errors = ocx.try_evaluate_obligations();
|
||||
if !errors.is_empty() {
|
||||
fulfillment_errors.append(&mut errors);
|
||||
return false;
|
||||
|
||||
@@ -1906,7 +1906,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
// them to deal with defining uses in `method_autoderef_steps`.
|
||||
if self.next_trait_solver() {
|
||||
ocx.register_obligations(instantiate_self_ty_obligations.iter().cloned());
|
||||
let errors = ocx.select_where_possible();
|
||||
let errors = ocx.try_evaluate_obligations();
|
||||
if !errors.is_empty() {
|
||||
unreachable!("unexpected autoderef error {errors:?}");
|
||||
}
|
||||
@@ -2103,7 +2103,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// Evaluate those obligations to see if they might possibly hold.
|
||||
for error in ocx.select_where_possible() {
|
||||
for error in ocx.try_evaluate_obligations() {
|
||||
result = ProbeResult::NoMatch;
|
||||
let nested_predicate = self.resolve_vars_if_possible(error.obligation.predicate);
|
||||
if let Some(trait_predicate) = trait_predicate
|
||||
@@ -2143,7 +2143,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// Evaluate those obligations to see if they might possibly hold.
|
||||
for error in ocx.select_where_possible() {
|
||||
for error in ocx.try_evaluate_obligations() {
|
||||
result = ProbeResult::NoMatch;
|
||||
possibly_unsatisfied_predicates.push((
|
||||
error.obligation.predicate,
|
||||
@@ -2230,7 +2230,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
};
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
let self_ty = ocx.register_infer_ok_obligations(ok);
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
debug!("failed to prove instantiate self_ty obligations");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1030,7 +1030,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&self.infcx);
|
||||
ocx.register_obligation(obligation);
|
||||
Err(ocx.select_all_or_error())
|
||||
Err(ocx.evaluate_obligations_error_on_ambiguity())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
T: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
// Select everything, returning errors.
|
||||
let errors = fulfill_cx.select_all_or_error(self);
|
||||
let errors = fulfill_cx.evaluate_obligations_error_on_ambiguity(self);
|
||||
|
||||
// True error!
|
||||
if errors.iter().any(|e| e.is_true_error()) {
|
||||
|
||||
@@ -72,6 +72,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
|
||||
self.register_predicate_obligation(infcx, obligation);
|
||||
}
|
||||
}
|
||||
|
||||
/// Go over the list of pending obligations and try to evaluate them.
|
||||
///
|
||||
/// For each result:
|
||||
@@ -81,7 +82,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
|
||||
///
|
||||
/// Returns a list of errors from obligations that evaluated to Err.
|
||||
#[must_use]
|
||||
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E>;
|
||||
fn try_evaluate_obligations(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E>;
|
||||
|
||||
fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E>;
|
||||
|
||||
@@ -94,8 +95,8 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
|
||||
///
|
||||
/// Returns a list of errors from obligations that evaluated to Ambiguous or Err.
|
||||
#[must_use]
|
||||
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
|
||||
let errors = self.select_where_possible(infcx);
|
||||
fn evaluate_obligations_error_on_ambiguity(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
|
||||
let errors = self.try_evaluate_obligations(infcx);
|
||||
if !errors.is_empty() {
|
||||
return errors;
|
||||
}
|
||||
@@ -108,7 +109,7 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx {
|
||||
fn pending_obligations(&self) -> PredicateObligations<'tcx>;
|
||||
|
||||
/// Among all pending obligations, collect those are stalled on a inference variable which has
|
||||
/// changed since the last call to `select_where_possible`. Those obligations are marked as
|
||||
/// changed since the last call to `try_evaluate_obligations`. Those obligations are marked as
|
||||
/// successful and returned.
|
||||
fn drain_stalled_obligations_for_coroutines(
|
||||
&mut self,
|
||||
|
||||
@@ -180,5 +180,5 @@ fn suggest_question_mark<'tcx>(
|
||||
into_iterator_did,
|
||||
);
|
||||
|
||||
ocx.select_all_or_error().is_empty()
|
||||
ocx.evaluate_obligations_error_on_ambiguity().is_empty()
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
let assoc_pred =
|
||||
ocx.normalize(&traits::ObligationCause::dummy(), cx.param_env, assoc_pred);
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
// Can't normalize for some reason...?
|
||||
continue;
|
||||
}
|
||||
@@ -166,7 +166,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||
// If that predicate doesn't hold modulo regions (but passed during type-check),
|
||||
// then we must've taken advantage of the hack in `project_and_unify_types` where
|
||||
// we replace opaques with inference vars. Emit a warning!
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
// If it's a trait bound and an opaque that doesn't satisfy it,
|
||||
// then we can emit a suggestion to add the bound.
|
||||
let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
|
||||
|
||||
@@ -1429,7 +1429,7 @@ fn check_field_tys_sized<'tcx>(
|
||||
);
|
||||
}
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
debug!(?errors);
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
|
||||
@@ -623,7 +623,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
param_env,
|
||||
pred,
|
||||
));
|
||||
ocx.select_all_or_error().is_empty()
|
||||
ocx.evaluate_obligations_error_on_ambiguity().is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2013,7 +2013,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
let sig = ocx.normalize(&cause, param_env, sig);
|
||||
|
||||
// proc macro is not WF.
|
||||
let errors = ocx.select_where_possible();
|
||||
let errors = ocx.try_evaluate_obligations();
|
||||
if !errors.is_empty() {
|
||||
return;
|
||||
}
|
||||
@@ -2081,7 +2081,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
||||
self.abort.set(true);
|
||||
}
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
self.abort.set(true);
|
||||
|
||||
@@ -56,7 +56,7 @@ pub fn ensure_wf<'tcx>(
|
||||
pred,
|
||||
);
|
||||
ocx.register_obligation(obligation);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
false
|
||||
|
||||
@@ -83,7 +83,7 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>(
|
||||
});
|
||||
ocx.register_obligations(obligations);
|
||||
|
||||
ocx.select_where_possible().is_empty()
|
||||
ocx.try_evaluate_obligations().is_empty()
|
||||
})
|
||||
};
|
||||
|
||||
@@ -113,7 +113,7 @@ pub fn compute_applicable_impls_for_diagnostics<'tcx>(
|
||||
return false;
|
||||
}
|
||||
|
||||
ocx.select_where_possible().is_empty()
|
||||
ocx.try_evaluate_obligations().is_empty()
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -1470,7 +1470,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
//
|
||||
// we intentionally drop errors from normalization here,
|
||||
// since the normalization is just done to improve the error message.
|
||||
let _ = ocx.select_where_possible();
|
||||
let _ = ocx.try_evaluate_obligations();
|
||||
|
||||
if let Err(new_err) =
|
||||
ocx.eq(&obligation.cause, obligation.param_env, data.term, normalized_term)
|
||||
@@ -2086,7 +2086,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
)
|
||||
}),
|
||||
);
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2102,7 +2102,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
{
|
||||
terrs.push(terr);
|
||||
}
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -3440,7 +3440,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
);
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
ocx.register_obligation(obligation);
|
||||
if ocx.select_all_or_error().is_empty() {
|
||||
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
return Ok((
|
||||
self.tcx
|
||||
.fn_trait_kind_from_def_id(trait_def_id)
|
||||
|
||||
@@ -4590,7 +4590,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
param_env,
|
||||
projection,
|
||||
));
|
||||
if ocx.select_where_possible().is_empty()
|
||||
if ocx.try_evaluate_obligations().is_empty()
|
||||
&& let ty = self.resolve_vars_if_possible(ty)
|
||||
&& !ty.is_ty_var()
|
||||
{
|
||||
@@ -4737,7 +4737,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||
pred,
|
||||
));
|
||||
});
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
// encountered errors.
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
let Ok(()) = ocx.eq(&ObligationCause::dummy(), param_env, a, b) else {
|
||||
return false;
|
||||
};
|
||||
ocx.select_where_possible().is_empty()
|
||||
ocx.try_evaluate_obligations().is_empty()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
param_env,
|
||||
ty::TraitRef::new(self.tcx, trait_def_id, [ty]),
|
||||
));
|
||||
let errors = ocx.select_where_possible();
|
||||
let errors = ocx.try_evaluate_obligations();
|
||||
// Find the original predicate in the list of predicates that could definitely not be fulfilled.
|
||||
// If it is in that list, then we know this doesn't even shallowly implement the trait.
|
||||
// If it is not in that list, it was fulfilled, but there may be nested obligations, which we don't care about here.
|
||||
|
||||
@@ -60,7 +60,7 @@ struct ObligationStorage<'tcx> {
|
||||
/// Obligations which resulted in an overflow in fulfillment itself.
|
||||
///
|
||||
/// We cannot eagerly return these as error so we instead store them here
|
||||
/// to avoid recomputing them each time `select_where_possible` is called.
|
||||
/// to avoid recomputing them each time `try_evaluate_obligations` is called.
|
||||
/// This also allows us to return the correct `FulfillmentError` for them.
|
||||
overflowed: Vec<PredicateObligation<'tcx>>,
|
||||
pending: PendingObligations<'tcx>,
|
||||
@@ -101,7 +101,7 @@ impl<'tcx> ObligationStorage<'tcx> {
|
||||
// IMPORTANT: we must not use solve any inference variables in the obligations
|
||||
// as this is all happening inside of a probe. We use a probe to make sure
|
||||
// we get all obligations involved in the overflow. We pretty much check: if
|
||||
// we were to do another step of `select_where_possible`, which goals would
|
||||
// we were to do another step of `try_evaluate_obligations`, which goals would
|
||||
// change.
|
||||
// FIXME: <https://github.com/Gankra/thin-vec/pull/66> is merged, this can be removed.
|
||||
self.overflowed.extend(
|
||||
@@ -179,7 +179,7 @@ where
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
|
||||
fn try_evaluate_obligations(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
|
||||
assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots());
|
||||
let mut errors = Vec::new();
|
||||
loop {
|
||||
|
||||
@@ -76,7 +76,7 @@ impl<'tcx> NormalizesToTermHack<'tcx> {
|
||||
self.unconstrained_term,
|
||||
)?;
|
||||
f(&ocx);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if errors.is_empty() {
|
||||
Ok(Certainty::Yes)
|
||||
} else if errors.iter().all(|e| !e.is_true_error()) {
|
||||
|
||||
@@ -79,7 +79,7 @@ where
|
||||
stalled_coroutine_goals: vec![],
|
||||
};
|
||||
let value = value.try_fold_with(&mut folder)?;
|
||||
let errors = folder.fulfill_cx.select_all_or_error(at.infcx);
|
||||
let errors = folder.fulfill_cx.evaluate_obligations_error_on_ambiguity(at.infcx);
|
||||
if errors.is_empty() { Ok((value, folder.stalled_coroutine_goals)) } else { Err(errors) }
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ where
|
||||
);
|
||||
|
||||
self.fulfill_cx.register_predicate_obligation(infcx, obligation);
|
||||
self.select_all_and_stall_coroutine_predicates()?;
|
||||
self.evaluate_all_error_on_ambiguity_stall_coroutine_predicates()?;
|
||||
|
||||
// Alias is guaranteed to be fully structurally resolved,
|
||||
// so we can super fold here.
|
||||
@@ -143,8 +143,8 @@ where
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn select_all_and_stall_coroutine_predicates(&mut self) -> Result<(), Vec<E>> {
|
||||
let errors = self.fulfill_cx.select_where_possible(self.at.infcx);
|
||||
fn evaluate_all_error_on_ambiguity_stall_coroutine_predicates(&mut self) -> Result<(), Vec<E>> {
|
||||
let errors = self.fulfill_cx.try_evaluate_obligations(self.at.infcx);
|
||||
if !errors.is_empty() {
|
||||
return Err(errors);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
// an additional sanity check.
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
ocx.register_bound(ObligationCause::dummy(), full_env, ty, trait_did);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
panic!("Unable to fulfill trait {trait_did:?} for '{ty:?}': {errors:?}");
|
||||
}
|
||||
|
||||
@@ -371,7 +371,7 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
|
||||
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
ocx.register_obligations(obligations.iter().cloned());
|
||||
let hard_errors = ocx.select_where_possible();
|
||||
let hard_errors = ocx.try_evaluate_obligations();
|
||||
if !hard_errors.is_empty() {
|
||||
assert!(
|
||||
hard_errors.iter().all(|e| e.is_true_error()),
|
||||
@@ -386,7 +386,7 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
|
||||
let ambiguities = ocx.into_pending_obligations();
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
|
||||
ocx.register_obligations(ambiguities);
|
||||
let errors_and_ambiguities = ocx.select_all_or_error();
|
||||
let errors_and_ambiguities = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
// We only care about the obligations that are *definitely* true errors.
|
||||
// Ambiguities do not prove the disjointness of two impls.
|
||||
let (errors, ambiguities): (Vec<_>, Vec<_>) =
|
||||
@@ -623,7 +623,7 @@ fn try_prove_negated_where_clause<'tcx>(
|
||||
param_env,
|
||||
negative_predicate,
|
||||
));
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -743,7 +743,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
|
||||
ty = ocx
|
||||
.structurally_normalize_ty(&ObligationCause::dummy(), param_env, ty)
|
||||
.map_err(|_| ())?;
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
return Err(());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ fn satisfied_from_param_env<'tcx>(
|
||||
if self.infcx.probe(|_| {
|
||||
let ocx = ObligationCtxt::new(self.infcx);
|
||||
ocx.eq(&ObligationCause::dummy(), self.param_env, c, self.ct).is_ok()
|
||||
&& ocx.select_all_or_error().is_empty()
|
||||
&& ocx.evaluate_obligations_error_on_ambiguity().is_empty()
|
||||
}) {
|
||||
self.single_match = match self.single_match {
|
||||
None => Some(Ok(c)),
|
||||
@@ -217,7 +217,7 @@ fn satisfied_from_param_env<'tcx>(
|
||||
if let Some(Ok(c)) = single_match {
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
assert!(ocx.eq(&ObligationCause::dummy(), param_env, c, ct).is_ok());
|
||||
assert!(ocx.select_all_or_error().is_empty());
|
||||
assert!(ocx.evaluate_obligations_error_on_ambiguity().is_empty());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -202,14 +202,30 @@ where
|
||||
.map(|infer_ok| self.register_infer_ok_obligations(infer_ok))
|
||||
}
|
||||
|
||||
/// Go over the list of pending obligations and try to evaluate them.
|
||||
///
|
||||
/// For each result:
|
||||
/// Ok: remove the obligation from the list
|
||||
/// Ambiguous: leave the obligation in the list to be evaluated later
|
||||
/// Err: remove the obligation from the list and return an error
|
||||
///
|
||||
/// Returns a list of errors from obligations that evaluated to Err.
|
||||
#[must_use]
|
||||
pub fn select_where_possible(&self) -> Vec<E> {
|
||||
self.engine.borrow_mut().select_where_possible(self.infcx)
|
||||
pub fn try_evaluate_obligations(&self) -> Vec<E> {
|
||||
self.engine.borrow_mut().try_evaluate_obligations(self.infcx)
|
||||
}
|
||||
|
||||
/// Evaluate all pending obligations, return error if they can't be evaluated.
|
||||
///
|
||||
/// For each result:
|
||||
/// Ok: remove the obligation from the list
|
||||
/// Ambiguous: remove the obligation from the list and return an error
|
||||
/// Err: remove the obligation from the list and return an error
|
||||
///
|
||||
/// Returns a list of errors from obligations that evaluated to Ambiguous or Err.
|
||||
#[must_use]
|
||||
pub fn select_all_or_error(&self) -> Vec<E> {
|
||||
self.engine.borrow_mut().select_all_or_error(self.infcx)
|
||||
pub fn evaluate_obligations_error_on_ambiguity(&self) -> Vec<E> {
|
||||
self.engine.borrow_mut().evaluate_obligations_error_on_ambiguity(self.infcx)
|
||||
}
|
||||
|
||||
/// Returns the not-yet-processed and stalled obligations from the
|
||||
|
||||
@@ -52,11 +52,11 @@ impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
|
||||
/// consists of a list of obligations that must be (eventually)
|
||||
/// satisfied. The job is to track which are satisfied, which yielded
|
||||
/// errors, and which are still pending. At any point, users can call
|
||||
/// `select_where_possible`, and the fulfillment context will try to do
|
||||
/// `try_evaluate_obligations`, and the fulfillment context will try to do
|
||||
/// selection, retaining only those obligations that remain
|
||||
/// ambiguous. This may be helpful in pushing type inference
|
||||
/// along. Once all type inference constraints have been generated, the
|
||||
/// method `select_all_or_error` can be used to report any remaining
|
||||
/// method `evaluate_obligations_error_on_ambiguity` can be used to report any remaining
|
||||
/// ambiguous cases as errors.
|
||||
pub struct FulfillmentContext<'tcx, E: 'tcx> {
|
||||
/// A list of all obligations that have been registered with this
|
||||
@@ -163,7 +163,7 @@ where
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
|
||||
fn try_evaluate_obligations(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> {
|
||||
let selcx = SelectionContext::new(infcx);
|
||||
self.select(selcx)
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
|
||||
ty::ClauseKind::UnstableFeature(sym::unsized_const_params),
|
||||
));
|
||||
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
return Err(ConstParamTyImplementationError::UnsizedConstParamsFeatureRequired);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,7 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
|
||||
tcx.require_lang_item(LangItem::ConstParamTy, parent_cause.span),
|
||||
);
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
infringing_inner_tys.push((inner_ty, InfringingFieldsReason::Fulfill(errors)));
|
||||
continue;
|
||||
@@ -235,7 +235,7 @@ pub fn all_fields_implement_trait<'tcx>(
|
||||
ObligationCause::dummy_with_span(field_ty_span)
|
||||
};
|
||||
let ty = ocx.normalize(&normalization_cause, param_env, unnormalized_ty);
|
||||
let normalization_errors = ocx.select_where_possible();
|
||||
let normalization_errors = ocx.try_evaluate_obligations();
|
||||
|
||||
// NOTE: The post-normalization type may also reference errors,
|
||||
// such as when we project to a missing type or we have a mismatch
|
||||
@@ -252,7 +252,7 @@ pub fn all_fields_implement_trait<'tcx>(
|
||||
ty,
|
||||
trait_def_id,
|
||||
);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
infringing.push((field, ty, InfringingFieldsReason::Fulfill(errors)));
|
||||
}
|
||||
|
||||
@@ -231,7 +231,7 @@ fn pred_known_to_hold_modulo_regions<'tcx>(
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
ocx.register_obligation(obligation);
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
match errors.as_slice() {
|
||||
// Only known to hold if we did no inference.
|
||||
[] => infcx.resolve_vars_if_possible(goal) == goal,
|
||||
@@ -273,7 +273,7 @@ fn do_normalize_predicates<'tcx>(
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
let predicates = ocx.normalize(&cause, elaborated_env, predicates);
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return Err(reported);
|
||||
@@ -738,13 +738,13 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
|
||||
ocx.register_obligation(obligation);
|
||||
}
|
||||
|
||||
// Use `select_where_possible` to only return impossible for true errors,
|
||||
// Use `try_evaluate_obligations` to only return impossible for true errors,
|
||||
// and not ambiguities or overflows. Since the new trait solver forces
|
||||
// some currently undetected overlap between `dyn Trait: Trait` built-in
|
||||
// vs user-written impls to AMBIGUOUS, this may return ambiguity even
|
||||
// with no infer vars. There may also be ways to encounter ambiguity due
|
||||
// to post-mono overflow.
|
||||
let true_errors = ocx.select_where_possible();
|
||||
let true_errors = ocx.try_evaluate_obligations();
|
||||
if !true_errors.is_empty() {
|
||||
return true;
|
||||
}
|
||||
@@ -853,7 +853,7 @@ fn is_impossible_associated_item(
|
||||
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
ocx.register_obligations(predicates_for_trait);
|
||||
!ocx.select_where_possible().is_empty()
|
||||
!ocx.try_evaluate_obligations().is_empty()
|
||||
}
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
|
||||
@@ -73,7 +73,7 @@ impl<'tcx> At<'_, 'tcx> {
|
||||
let value = self
|
||||
.normalize(value)
|
||||
.into_value_registering_obligations(self.infcx, &mut *fulfill_cx);
|
||||
let errors = fulfill_cx.select_all_or_error(self.infcx);
|
||||
let errors = fulfill_cx.evaluate_obligations_error_on_ambiguity(self.infcx);
|
||||
let value = self.infcx.resolve_vars_if_possible(value);
|
||||
if errors.is_empty() {
|
||||
Ok(value)
|
||||
|
||||
@@ -199,7 +199,7 @@ where
|
||||
// Flush errors b/c `deeply_normalize` doesn't expect pending
|
||||
// obligations, and we may have pending obligations from the
|
||||
// branch above (from other types).
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
return Err(errors);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
ocx.register_obligation(obligation.clone());
|
||||
let mut result = EvaluationResult::EvaluatedToOk;
|
||||
for error in ocx.select_all_or_error() {
|
||||
for error in ocx.evaluate_obligations_error_on_ambiguity() {
|
||||
if error.is_true_error() {
|
||||
return Ok(EvaluationResult::EvaluatedToErr);
|
||||
} else {
|
||||
|
||||
@@ -94,7 +94,7 @@ where
|
||||
let value = op(&ocx).map_err(|_| {
|
||||
infcx.dcx().span_delayed_bug(span, format!("error performing operation: {name}"))
|
||||
})?;
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if errors.is_empty() {
|
||||
Ok(value)
|
||||
} else if let Err(guar) = infcx.tcx.check_potentially_region_dependent_goals(root_def_id) {
|
||||
|
||||
@@ -164,7 +164,7 @@ fn fulfill_implication<'tcx>(
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
let source_trait_ref = ocx.normalize(cause, param_env, source_trait_ref);
|
||||
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
infcx.dcx().span_delayed_bug(
|
||||
infcx.tcx.def_span(source_impl),
|
||||
format!("failed to fully normalize {source_trait_ref}"),
|
||||
@@ -197,7 +197,7 @@ fn fulfill_implication<'tcx>(
|
||||
let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates);
|
||||
ocx.register_obligations(obligations);
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
// no dice!
|
||||
debug!(
|
||||
@@ -295,7 +295,7 @@ pub(super) fn specializes(
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let specializing_impl_trait_ref = ocx.normalize(cause, param_env, specializing_impl_trait_ref);
|
||||
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
if !ocx.evaluate_obligations_error_on_ambiguity().is_empty() {
|
||||
infcx.dcx().span_delayed_bug(
|
||||
infcx.tcx.def_span(specializing_impl_def_id),
|
||||
format!("failed to fully normalize {specializing_impl_trait_ref}"),
|
||||
@@ -331,7 +331,7 @@ pub(super) fn specializes(
|
||||
let obligations = predicates_for_generics(|_, _| cause.clone(), param_env, predicates);
|
||||
ocx.register_obligations(obligations);
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
// no dice!
|
||||
debug!(
|
||||
@@ -367,7 +367,7 @@ pub(super) fn specializes(
|
||||
)
|
||||
}));
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
// no dice!
|
||||
debug!(
|
||||
|
||||
@@ -52,7 +52,7 @@ impl<'tcx> At<'_, 'tcx> {
|
||||
);
|
||||
|
||||
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
|
||||
let errors = fulfill_cx.select_where_possible(self.infcx);
|
||||
let errors = fulfill_cx.try_evaluate_obligations(self.infcx);
|
||||
if !errors.is_empty() {
|
||||
return Err(errors);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ pub(crate) fn codegen_select_candidate<'tcx>(
|
||||
// In principle, we only need to do this so long as `impl_source`
|
||||
// contains unbound type parameters. It could be a slight
|
||||
// optimization to stop iterating early.
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if !errors.is_empty() {
|
||||
// `rustc_monomorphize::collector` assumes there are no type errors.
|
||||
// Cycle errors are the only post-monomorphization errors possible; emit them now so
|
||||
|
||||
@@ -63,7 +63,7 @@ fn compute_assumptions<'tcx>(
|
||||
ty::ClauseKind::WellFormed(ty.into()),
|
||||
)
|
||||
}));
|
||||
let _errors = ocx.select_all_or_error();
|
||||
let _errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
|
||||
let region_obligations = infcx.take_registered_region_obligations();
|
||||
let region_assumptions = infcx.take_registered_region_assumptions();
|
||||
|
||||
@@ -45,7 +45,7 @@ fn normalize_canonicalized_projection_ty<'tcx>(
|
||||
// are recursive (given some generic parameters of the opaque's type variables).
|
||||
// In that case, we may only realize a cycle error when calling
|
||||
// `normalize_erasing_regions` in mono.
|
||||
let errors = ocx.select_where_possible();
|
||||
let errors = ocx.try_evaluate_obligations();
|
||||
if !errors.is_empty() {
|
||||
// Rustdoc may attempt to normalize type alias types which are not
|
||||
// well-formed. Rustdoc also normalizes types that are just not
|
||||
|
||||
@@ -28,7 +28,7 @@ fn has_structural_eq_impl<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool {
|
||||
//
|
||||
// 2. We are sometimes doing future-incompatibility lints for
|
||||
// now, so we do not want unconditional errors here.
|
||||
ocx.select_all_or_error().is_empty()
|
||||
ocx.evaluate_obligations_error_on_ambiguity().is_empty()
|
||||
}
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
|
||||
@@ -90,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
let cause = traits::ObligationCause::misc(span, fn_def_id);
|
||||
ocx.register_bound(cause, cx.param_env, ret_ty, send_trait);
|
||||
let send_errors = ocx.select_all_or_error();
|
||||
let send_errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
|
||||
// Allow errors that try to prove `Send` for types that "mention" a generic parameter at the "top
|
||||
// level".
|
||||
|
||||
@@ -475,7 +475,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
|
||||
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
ocx.register_obligations(impl_src.nested_obligations());
|
||||
ocx.select_all_or_error().is_empty()
|
||||
ocx.evaluate_obligations_error_on_ambiguity().is_empty()
|
||||
}
|
||||
|
||||
!ty.needs_drop(tcx, ConstCx::new(tcx, body).typing_env)
|
||||
|
||||
@@ -304,7 +304,7 @@ fn structurally_normalize_ty<'db>(
|
||||
// evaluate/fulfill mismatches, but that's not a reason for an ICE.
|
||||
return None;
|
||||
};
|
||||
let errors = ocx.select_where_possible();
|
||||
let errors = ocx.try_evaluate_obligations();
|
||||
if !errors.is_empty() {
|
||||
unreachable!();
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
|
||||
Ok(InferOk { value, obligations }) => {
|
||||
let mut ocx = ObligationCtxt::new(this.infer_ctxt());
|
||||
ocx.register_obligations(obligations);
|
||||
if ocx.select_where_possible().is_empty() {
|
||||
if ocx.try_evaluate_obligations().is_empty() {
|
||||
Ok(InferOk { value, obligations: ocx.into_pending_obligations() })
|
||||
} else {
|
||||
Err(TypeError::Mismatch)
|
||||
@@ -743,7 +743,7 @@ impl<'a, 'b, 'db> Coerce<'a, 'b, 'db> {
|
||||
Some(PredicateKind::AliasRelate(..)) => {
|
||||
let mut ocx = ObligationCtxt::new(self.infer_ctxt());
|
||||
ocx.register_obligation(obligation);
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
return Err(TypeError::Mismatch);
|
||||
}
|
||||
coercion.obligations.extend(ocx.into_pending_obligations());
|
||||
@@ -1119,7 +1119,7 @@ impl<'db> InferenceContext<'db> {
|
||||
prev_ty,
|
||||
new_ty,
|
||||
)?;
|
||||
if ocx.select_where_possible().is_empty() {
|
||||
if ocx.try_evaluate_obligations().is_empty() {
|
||||
Ok(InferOk { value, obligations: ocx.into_pending_obligations() })
|
||||
} else {
|
||||
Err(TypeError::Mismatch)
|
||||
|
||||
@@ -2151,7 +2151,7 @@ impl<'db> InferenceContext<'db> {
|
||||
expected_output.to_nextsolver(interner),
|
||||
formal_output,
|
||||
)?;
|
||||
if !ocx.select_where_possible().is_empty() {
|
||||
if !ocx.try_evaluate_obligations().is_empty() {
|
||||
return Err(crate::next_solver::TypeError::Mismatch);
|
||||
}
|
||||
|
||||
|
||||
@@ -818,7 +818,7 @@ impl<'db> InferenceTable<'db> {
|
||||
}
|
||||
|
||||
pub(crate) fn select_obligations_where_possible(&mut self) {
|
||||
self.fulfillment_cx.select_where_possible(&self.infer_ctxt);
|
||||
self.fulfillment_cx.try_evaluate_obligations(&self.infer_ctxt);
|
||||
}
|
||||
|
||||
pub(super) fn register_predicate(
|
||||
|
||||
@@ -1785,7 +1785,7 @@ fn is_valid_trait_method_candidate(
|
||||
let mut ctxt = ObligationCtxt::new(&table.infer_ctxt);
|
||||
ctxt.register_obligations(infer_ok.into_obligations());
|
||||
// FIXME: Are we doing this correctly? Probably better to follow rustc more closely.
|
||||
check_that!(ctxt.select_where_possible().is_empty());
|
||||
check_that!(ctxt.try_evaluate_obligations().is_empty());
|
||||
}
|
||||
|
||||
check_that!(table.unify(receiver_ty, &expected_receiver));
|
||||
@@ -1871,7 +1871,7 @@ fn is_valid_impl_fn_candidate(
|
||||
)
|
||||
}));
|
||||
|
||||
if ctxt.select_where_possible().is_empty() {
|
||||
if ctxt.try_evaluate_obligations().is_empty() {
|
||||
IsValidCandidate::Yes
|
||||
} else {
|
||||
IsValidCandidate::No
|
||||
|
||||
@@ -54,7 +54,7 @@ struct ObligationStorage<'db> {
|
||||
/// Obligations which resulted in an overflow in fulfillment itself.
|
||||
///
|
||||
/// We cannot eagerly return these as error so we instead store them here
|
||||
/// to avoid recomputing them each time `select_where_possible` is called.
|
||||
/// to avoid recomputing them each time `try_evaluate_obligations` is called.
|
||||
/// This also allows us to return the correct `FulfillmentError` for them.
|
||||
overflowed: Vec<PredicateObligation<'db>>,
|
||||
pending: PendingObligations<'db>,
|
||||
@@ -95,7 +95,7 @@ impl<'db> ObligationStorage<'db> {
|
||||
// IMPORTANT: we must not use solve any inference variables in the obligations
|
||||
// as this is all happening inside of a probe. We use a probe to make sure
|
||||
// we get all obligations involved in the overflow. We pretty much check: if
|
||||
// we were to do another step of `select_where_possible`, which goals would
|
||||
// we were to do another step of `try_evaluate_obligations`, which goals would
|
||||
// change.
|
||||
// FIXME: <https://github.com/Gankra/thin-vec/pull/66> is merged, this can be removed.
|
||||
self.overflowed.extend(
|
||||
@@ -131,7 +131,7 @@ impl<'db> FulfillmentCtxt<'db> {
|
||||
infcx: &InferCtxt<'db>,
|
||||
obligation: PredicateObligation<'db>,
|
||||
) {
|
||||
// FIXME: See the comment in `select_where_possible()`.
|
||||
// FIXME: See the comment in `try_evaluate_obligations()`.
|
||||
// assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots());
|
||||
self.obligations.register(obligation, None);
|
||||
}
|
||||
@@ -141,7 +141,7 @@ impl<'db> FulfillmentCtxt<'db> {
|
||||
infcx: &InferCtxt<'db>,
|
||||
obligations: impl IntoIterator<Item = PredicateObligation<'db>>,
|
||||
) {
|
||||
// FIXME: See the comment in `select_where_possible()`.
|
||||
// FIXME: See the comment in `try_evaluate_obligations()`.
|
||||
// assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots());
|
||||
obligations.into_iter().for_each(|obligation| self.obligations.register(obligation, None));
|
||||
}
|
||||
@@ -158,7 +158,7 @@ impl<'db> FulfillmentCtxt<'db> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn select_where_possible(
|
||||
pub(crate) fn try_evaluate_obligations(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'db>,
|
||||
) -> Vec<NextSolverError<'db>> {
|
||||
@@ -223,11 +223,11 @@ impl<'db> FulfillmentCtxt<'db> {
|
||||
errors
|
||||
}
|
||||
|
||||
pub(crate) fn select_all_or_error(
|
||||
pub(crate) fn evaluate_obligations_error_on_ambiguity(
|
||||
&mut self,
|
||||
infcx: &InferCtxt<'db>,
|
||||
) -> Vec<NextSolverError<'db>> {
|
||||
let errors = self.select_where_possible(infcx);
|
||||
let errors = self.try_evaluate_obligations(infcx);
|
||||
if !errors.is_empty() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ impl<'db> NormalizesToTermHack<'db> {
|
||||
let mut ocx = ObligationCtxt::new(infcx);
|
||||
ocx.eq(&ObligationCause::dummy(), param_env, self.term, self.unconstrained_term)?;
|
||||
f(&mut ocx);
|
||||
let errors = ocx.select_all_or_error();
|
||||
let errors = ocx.evaluate_obligations_error_on_ambiguity();
|
||||
if errors.is_empty() {
|
||||
Ok(Certainty::Yes)
|
||||
} else if errors.iter().all(|e| !matches!(e, NextSolverError::TrueError(_))) {
|
||||
|
||||
@@ -77,7 +77,7 @@ where
|
||||
stalled_coroutine_goals: vec![],
|
||||
};
|
||||
let value = value.try_fold_with(&mut folder)?;
|
||||
let errors = folder.fulfill_cx.select_all_or_error(at.infcx);
|
||||
let errors = folder.fulfill_cx.evaluate_obligations_error_on_ambiguity(at.infcx);
|
||||
if errors.is_empty() { Ok((value, folder.stalled_coroutine_goals)) } else { Err(errors) }
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ impl<'db> NormalizationFolder<'_, 'db> {
|
||||
fn select_all_and_stall_coroutine_predicates(
|
||||
&mut self,
|
||||
) -> Result<(), Vec<NextSolverError<'db>>> {
|
||||
let errors = self.fulfill_cx.select_where_possible(self.at.infcx);
|
||||
let errors = self.fulfill_cx.try_evaluate_obligations(self.at.infcx);
|
||||
if !errors.is_empty() {
|
||||
return Err(errors);
|
||||
}
|
||||
|
||||
@@ -144,13 +144,13 @@ impl<'a, 'db> ObligationCtxt<'a, 'db> {
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn select_where_possible(&mut self) -> Vec<NextSolverError<'db>> {
|
||||
self.engine.select_where_possible(self.infcx)
|
||||
pub fn try_evaluate_obligations(&mut self) -> Vec<NextSolverError<'db>> {
|
||||
self.engine.try_evaluate_obligations(self.infcx)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn select_all_or_error(&mut self) -> Vec<NextSolverError<'db>> {
|
||||
self.engine.select_all_or_error(self.infcx)
|
||||
pub fn evaluate_obligations_error_on_ambiguity(&mut self) -> Vec<NextSolverError<'db>> {
|
||||
self.engine.evaluate_obligations_error_on_ambiguity(self.infcx)
|
||||
}
|
||||
|
||||
/// Returns the not-yet-processed and stalled obligations from the
|
||||
|
||||
@@ -47,7 +47,7 @@ impl<'db> At<'_, 'db> {
|
||||
);
|
||||
|
||||
fulfill_cx.register_predicate_obligation(self.infcx, obligation);
|
||||
let errors = fulfill_cx.select_where_possible(self.infcx);
|
||||
let errors = fulfill_cx.try_evaluate_obligations(self.infcx);
|
||||
if !errors.is_empty() {
|
||||
return Err(errors);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ fn foo() -> impl Default + Copy {
|
||||
// Make a tuple `(?x, ?y)` and equate it with `(impl Default, u32)`.
|
||||
// For us to try and prove a `Subtype(impl Default, u32)` obligation,
|
||||
// we have to instantiate both `?x` and `?y` without any
|
||||
// `select_where_possible` calls inbetween.
|
||||
// `try_evaluate_obligations` calls inbetween.
|
||||
let mut tup = &mut (x, y);
|
||||
let assign_tup = &mut (foo(), 1u32);
|
||||
tup = assign_tup;
|
||||
|
||||
Reference in New Issue
Block a user