use crate::infer::InferCtxt; use crate::traits::Obligation; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_middle::ty::{self, ToPredicate, Ty}; use super::FulfillmentError; use super::{ObligationCause, PredicateObligation}; pub trait TraitEngine<'tcx>: 'tcx { fn normalize_projection_type( &mut self, infcx: &InferCtxt<'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<'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: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx), }, ); } fn register_predicate_obligation( &mut self, infcx: &InferCtxt<'tcx>, obligation: PredicateObligation<'tcx>, ); fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec>; fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec>; fn pending_obligations(&self) -> Vec>; fn relationships(&mut self) -> &mut FxHashMap; } pub trait TraitEngineExt<'tcx> { fn register_predicate_obligations( &mut self, infcx: &InferCtxt<'tcx>, obligations: impl IntoIterator>, ); } impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T { fn register_predicate_obligations( &mut self, infcx: &InferCtxt<'tcx>, obligations: impl IntoIterator>, ) { for obligation in obligations { self.register_predicate_obligation(infcx, obligation); } } }