1 use crate::infer::InferCtxt;
2 use crate::traits::Obligation;
3 use rustc_data_structures::fx::FxHashMap;
5 use rustc_hir::def_id::DefId;
6 use rustc_middle::ty::{self, ToPredicate, Ty, WithConstness};
8 use super::FulfillmentError;
9 use super::{ObligationCause, PredicateObligation};
11 pub trait TraitEngine<'tcx>: 'tcx {
12 fn normalize_projection_type(
14 infcx: &InferCtxt<'_, 'tcx>,
15 param_env: ty::ParamEnv<'tcx>,
16 projection_ty: ty::ProjectionTy<'tcx>,
17 cause: ObligationCause<'tcx>,
20 /// Requires that `ty` must implement the trait with `def_id` in
21 /// the given environment. This trait must not have any type
22 /// parameters (except for `Self`).
25 infcx: &InferCtxt<'_, 'tcx>,
26 param_env: ty::ParamEnv<'tcx>,
29 cause: ObligationCause<'tcx>,
31 let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
32 self.register_predicate_obligation(
38 predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx),
43 fn register_predicate_obligation(
45 infcx: &InferCtxt<'_, 'tcx>,
46 obligation: PredicateObligation<'tcx>,
49 fn select_all_or_error(
51 infcx: &InferCtxt<'_, 'tcx>,
52 ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
54 fn select_all_with_constness_or_error(
56 infcx: &InferCtxt<'_, 'tcx>,
57 _constness: hir::Constness,
58 ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
59 self.select_all_or_error(infcx)
62 fn select_where_possible(
64 infcx: &InferCtxt<'_, 'tcx>,
65 ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
67 // FIXME(fee1-dead) this should not provide a default body for chalk as chalk should be updated
68 fn select_with_constness_where_possible(
70 infcx: &InferCtxt<'_, 'tcx>,
71 _constness: hir::Constness,
72 ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
73 self.select_where_possible(infcx)
76 fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
78 fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships>;
81 pub trait TraitEngineExt<'tcx> {
82 fn register_predicate_obligations(
84 infcx: &InferCtxt<'_, 'tcx>,
85 obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
89 impl<T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
90 fn register_predicate_obligations(
92 infcx: &InferCtxt<'_, 'tcx>,
93 obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
95 for obligation in obligations {
96 self.register_predicate_obligation(infcx, obligation);