use super::{
FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation, ObligationCause,
- ObligationCauseCode, OutputTypeParameterMismatch, Overflow, PredicateObligation,
- SelectionContext, SelectionError, TraitNotObjectSafe,
+ ObligationCauseCode, ObligationCtxt, OutputTypeParameterMismatch, Overflow,
+ PredicateObligation, SelectionContext, SelectionError, TraitNotObjectSafe,
};
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::{self, InferCtxt, TyCtxtInferExt};
-use crate::traits::engine::TraitEngineExt as _;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::query::normalize::AtExt as _;
use crate::traits::specialize::to_pretty_impl_header;
use rustc_hir::Node;
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::TypeTrace;
-use rustc_infer::traits::TraitEngine;
use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::ExpectedFound;
span: DUMMY_SP,
kind: TypeVariableOriginKind::MiscVariable,
});
- let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()]);
+ let trait_ref = self.tcx.mk_trait_ref(trait_def_id, [ty.skip_binder(), var]);
let obligation = Obligation::new(
self.tcx,
ObligationCause::dummy(),
param_env,
- ty.rebind(ty::TraitPredicate {
- trait_ref: ty::TraitRef::new(trait_def_id, substs),
- constness,
- polarity,
- }),
+ ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }),
);
- let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.tcx);
- fulfill_cx.register_predicate_obligation(self, obligation);
- if fulfill_cx.select_all_or_error(self).is_empty() {
+ let ocx = ObligationCtxt::new_in_snapshot(self);
+ ocx.register_obligation(obligation);
+ if ocx.select_all_or_error().is_empty() {
return Ok((
ty::ClosureKind::from_def_id(self.tcx, trait_def_id)
.expect("expected to map DefId to ClosureKind"),
if trait_predicate.skip_binder().self_ty().is_never()
&& self.fallback_has_occurred
{
- let predicate = trait_predicate.map_bound(|mut trait_pred| {
- trait_pred.trait_ref.substs = self.tcx.mk_substs_trait(
- self.tcx.mk_unit(),
- &trait_pred.trait_ref.substs[1..],
- );
- trait_pred
+ let predicate = trait_predicate.map_bound(|trait_pred| {
+ trait_pred.with_self_type(self.tcx, self.tcx.mk_unit())
});
let unit_obligation = obligation.with(tcx, predicate);
if self.predicate_may_hold(&unit_obligation) {
)
}
+ ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"),
+
ty::PredicateKind::TypeWellFormedFromEnv(..) => span_bug!(
span,
"TypeWellFormedFromEnv predicate should only exist in the environment"
param_env: ty::ParamEnv<'tcx>,
trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
) -> PredicateObligation<'tcx> {
- let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate {
- trait_ref: ty::TraitRef {
- substs: self.tcx.mk_substs_trait(*new_self_ty, &tr.trait_ref.substs[1..]),
- ..tr.trait_ref
- },
- ..*tr
- });
+ let trait_pred = trait_ref_and_ty
+ .map_bound(|(tr, new_self_ty)| tr.with_self_type(self.tcx, new_self_ty));
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred)
}
let obligation =
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred);
- self.predicate_may_hold(&obligation)
+ // We don't use `InferCtxt::predicate_may_hold` because that
+ // will re-run predicates that overflow locally, which ends up
+ // taking a really long time to compute.
+ self.evaluate_obligation(&obligation).map_or(false, |eval| eval.may_apply())
})
}