use rustc_middle::ty::{self, Ty};
use rustc_span::source_map::Span;
use rustc_target::spec::abi::Abi;
+use rustc_trait_selection::traits;
use rustc_trait_selection::traits::error_reporting::ArgKind;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use std::cmp;
expected_vid: ty::TyVid,
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
let mut expected_sig = None;
- // Even if we can't infer the full signature, we may be able to
- // infer the kind. This can occur when we elaborate a predicate
- // like `F : Fn<A>`. Note that due to subtyping we could encounter
- // many viable options, so pick the most restrictive.
let mut expected_kind = None;
- for obligation in self.obligations_for_self_ty(expected_vid) {
+ for obligation in traits::elaborate_obligations(
+ self.tcx,
+ // Reverse the obligations here, since `elaborate_*` uses a stack,
+ // and we want to keep inference generally in the same order of
+ // the registered obligations.
+ self.obligations_for_self_ty(expected_vid).rev().collect(),
+ ) {
debug!(?obligation.predicate);
let bound_predicate = obligation.predicate.kind();
+ // Given a Projection predicate, we can potentially infer
+ // the complete signature.
if expected_sig.is_none()
&& let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
{
- // Given a Projection predicate, we can potentially infer
- // the complete signature.
expected_sig = self.deduce_sig_from_projection(
Some(obligation.cause.span),
bound_predicate.rebind(proj_predicate),
);
}
+ // Even if we can't infer the full signature, we may be able to
+ // infer the kind. This can occur when we elaborate a predicate
+ // like `F : Fn<A>`. Note that due to subtyping we could encounter
+ // many viable options, so pick the most restrictive.
let trait_def_id = match bound_predicate.skip_binder() {
ty::PredicateKind::Projection(data) => {
Some(data.projection_ty.trait_def_id(self.tcx))