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::InferCtxtExt as _;
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::Item;
use rustc_hir::Node;
use rustc_infer::infer::error_reporting::TypeErrCtxt;
-use rustc_infer::infer::TypeTrace;
-use rustc_infer::traits::TraitEngine;
+use rustc_infer::infer::{InferOk, TypeTrace};
use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::ExpectedFound;
param_env,
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)
+ self.tcx
+ .fn_trait_kind_from_def_id(trait_def_id)
.expect("expected to map DefId to ClosureKind"),
ty.rebind(self.resolve_vars_if_possible(var)),
));
let bound_predicate = obligation.predicate.kind();
match bound_predicate.skip_binder() {
- ty::PredicateKind::Trait(trait_predicate) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
let trait_predicate = bound_predicate.rebind(trait_predicate);
let mut trait_predicate = self.resolve_vars_if_possible(trait_predicate);
}
ObligationCauseCode::BindingObligation(def_id, _)
| ObligationCauseCode::ItemObligation(def_id)
- if ty::ClosureKind::from_def_id(tcx, *def_id).is_some() =>
+ if tcx.is_fn_trait(*def_id) =>
{
err.code(rustc_errors::error_code!(E0059));
err.set_primary_message(format!(
);
}
- let is_fn_trait =
- ty::ClosureKind::from_def_id(tcx, trait_ref.def_id()).is_some();
+ let is_fn_trait = tcx.is_fn_trait(trait_ref.def_id());
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
*trait_ref.skip_binder().self_ty().kind()
{
// Note if the `FnMut` or `FnOnce` is less general than the trait we're trying
// to implement.
let selected_kind =
- ty::ClosureKind::from_def_id(self.tcx, trait_ref.def_id())
+ self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id())
.expect("expected to map DefId to ClosureKind");
if !implemented_kind.extends(selected_kind) {
err.note(
span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate)
}
- ty::PredicateKind::RegionOutlives(..)
- | ty::PredicateKind::Projection(..)
- | ty::PredicateKind::TypeOutlives(..) => {
+ ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
+ | ty::PredicateKind::Clause(ty::Clause::Projection(..))
+ | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) => {
let predicate = self.resolve_vars_if_possible(obligation.predicate);
struct_span_err!(
self.tcx.sess,
// FIXME: It should be possible to deal with `ForAll` in a cleaner way.
let bound_error = error.kind();
let (cond, error) = match (cond.kind().skip_binder(), bound_error.skip_binder()) {
- (ty::PredicateKind::Trait(..), ty::PredicateKind::Trait(error)) => {
- (cond, bound_error.rebind(error))
- }
+ (
+ ty::PredicateKind::Clause(ty::Clause::Trait(..)),
+ ty::PredicateKind::Clause(ty::Clause::Trait(error)),
+ ) => (cond, bound_error.rebind(error)),
_ => {
// FIXME: make this work in other cases too.
return false;
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
let bound_predicate = obligation.predicate.kind();
- if let ty::PredicateKind::Trait(implication) = bound_predicate.skip_binder() {
+ if let ty::PredicateKind::Clause(ty::Clause::Trait(implication)) =
+ bound_predicate.skip_binder()
+ {
let error = error.to_poly_trait_ref();
let implication = bound_predicate.rebind(implication.trait_ref);
// FIXME: I'm just not taking associated types at all here.
// this can fail if the problem was higher-ranked, in which
// cause I have no idea for a good error message.
let bound_predicate = predicate.kind();
- if let ty::PredicateKind::Projection(data) = bound_predicate.skip_binder() {
+ if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
+ bound_predicate.skip_binder()
+ {
let mut selcx = SelectionContext::new(self);
let data = self.replace_bound_vars_with_fresh_vars(
obligation.cause.span,
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
let secondary_span = match predicate.kind().skip_binder() {
- ty::PredicateKind::Projection(proj) => self
+ ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self
.tcx
.opt_associated_item(proj.projection_ty.item_def_id)
.and_then(|trait_assoc_item| {
let bound_predicate = predicate.kind();
let mut err = match bound_predicate.skip_binder() {
- ty::PredicateKind::Trait(data) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
let trait_ref = bound_predicate.rebind(data.trait_ref);
debug!(?trait_ref);
)
};
- let obligation = obligation.with(self.tcx, trait_ref.to_poly_trait_predicate());
- let mut selcx = SelectionContext::with_query_mode(
- &self,
- crate::traits::TraitQueryMode::Standard,
- );
+ let obligation = obligation.with(self.tcx, trait_ref);
+ let mut selcx = SelectionContext::new(&self);
match selcx.select_from_obligation(&obligation) {
Ok(None) => {
let impls = ambiguity::recompute_applicable_impls(self.infcx, &obligation);
if generics.params.iter().any(|p| p.name != kw::SelfUpper)
&& !snippet.ends_with('>')
&& !generics.has_impl_trait()
- && !self.tcx.fn_trait_kind_from_lang_item(def_id).is_some()
+ && !self.tcx.is_fn_trait(def_id)
{
// FIXME: To avoid spurious suggestions in functions where type arguments
// where already supplied, we check the snippet to make sure it doesn't
assert!(a.is_ty_var() && b.is_ty_var());
self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true)
}
- ty::PredicateKind::Projection(data) => {
+ ty::PredicateKind::Clause(ty::Clause::Projection(data)) => {
if predicate.references_error() || self.tainted_by_errors().is_some() {
return;
}
}
self.probe(|_| {
- let mut selcx = SelectionContext::new(self);
-
let cleaned_pred =
pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() });
- let cleaned_pred = super::project::normalize(
- &mut selcx,
- param_env,
- ObligationCause::dummy(),
- cleaned_pred,
- )
- .value;
+ let InferOk { value: cleaned_pred, .. } =
+ self.infcx.partially_normalize_associated_types_in(
+ ObligationCause::dummy(),
+ param_env,
+ cleaned_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())
})
}
err: &mut Diagnostic,
obligation: &PredicateObligation<'tcx>,
) {
- let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; };
+ let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = obligation.predicate.kind().skip_binder() else { return; };
let (ObligationCauseCode::BindingObligation(item_def_id, span)
| ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..))
= *obligation.cause.code().peel_derives() else { return; };