use crate::infer::InferCtxt; use crate::ty::{self, Ty, TyCtxt, ToPredicate}; use crate::traits::Obligation; use crate::hir::def_id::DefId; use super::{ChalkFulfillmentContext, FulfillmentContext, FulfillmentError}; use super::{ObligationCause, PredicateObligation}; pub trait TraitEngine<'tcx>: 'tcx { fn normalize_projection_type( &mut self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, projection_ty: ty::ProjectionTy<'tcx>, cause: ObligationCause<'tcx>, ) -> Ty<'tcx>; /// Requires that `ty` must implement the trait with `def_id` in /// the given environment. This trait must not have any type /// parameters (except for `Self`). fn register_bound( &mut self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>, def_id: DefId, cause: ObligationCause<'tcx>, ) { let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]), }; self.register_predicate_obligation(infcx, Obligation { cause, recursion_depth: 0, param_env, predicate: trait_ref.to_predicate() }); } fn register_predicate_obligation( &mut self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, obligation: PredicateObligation<'tcx>, ); fn select_all_or_error( &mut self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, ) -> Result<(), Vec>>; fn select_where_possible( &mut self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, ) -> Result<(), Vec>>; fn pending_obligations(&self) -> Vec>; } pub trait TraitEngineExt<'tcx> { fn register_predicate_obligations( &mut self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, obligations: impl IntoIterator>, ); } impl> TraitEngineExt<'tcx> for T { fn register_predicate_obligations( &mut self, infcx: &InferCtxt<'_, 'gcx, 'tcx>, obligations: impl IntoIterator>, ) { for obligation in obligations { self.register_predicate_obligation(infcx, obligation); } } } impl dyn TraitEngine<'tcx> { pub fn new(tcx: TyCtxt<'_, '_, 'tcx>) -> Box { if tcx.sess.opts.debugging_opts.chalk { Box::new(ChalkFulfillmentContext::new()) } else { Box::new(FulfillmentContext::new()) } } }