]> git.lizzy.rs Git - rust.git/blob - src/librustc/traits/engine.rs
Rollup merge of #67501 - oli-obk:test-slice-patterns, r=RalfJung
[rust.git] / src / librustc / traits / engine.rs
1 use crate::infer::InferCtxt;
2 use crate::traits::Obligation;
3 use crate::ty::{self, ToPredicate, Ty, TyCtxt};
4 use rustc_hir::def_id::DefId;
5
6 use super::{ChalkFulfillmentContext, FulfillmentContext, FulfillmentError};
7 use super::{ObligationCause, PredicateObligation};
8
9 pub trait TraitEngine<'tcx>: 'tcx {
10     fn normalize_projection_type(
11         &mut self,
12         infcx: &InferCtxt<'_, 'tcx>,
13         param_env: ty::ParamEnv<'tcx>,
14         projection_ty: ty::ProjectionTy<'tcx>,
15         cause: ObligationCause<'tcx>,
16     ) -> Ty<'tcx>;
17
18     /// Requires that `ty` must implement the trait with `def_id` in
19     /// the given environment. This trait must not have any type
20     /// parameters (except for `Self`).
21     fn register_bound(
22         &mut self,
23         infcx: &InferCtxt<'_, 'tcx>,
24         param_env: ty::ParamEnv<'tcx>,
25         ty: Ty<'tcx>,
26         def_id: DefId,
27         cause: ObligationCause<'tcx>,
28     ) {
29         let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
30         self.register_predicate_obligation(
31             infcx,
32             Obligation {
33                 cause,
34                 recursion_depth: 0,
35                 param_env,
36                 predicate: trait_ref.to_predicate(),
37             },
38         );
39     }
40
41     fn register_predicate_obligation(
42         &mut self,
43         infcx: &InferCtxt<'_, 'tcx>,
44         obligation: PredicateObligation<'tcx>,
45     );
46
47     fn select_all_or_error(
48         &mut self,
49         infcx: &InferCtxt<'_, 'tcx>,
50     ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
51
52     fn select_where_possible(
53         &mut self,
54         infcx: &InferCtxt<'_, 'tcx>,
55     ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
56
57     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
58 }
59
60 pub trait TraitEngineExt<'tcx> {
61     fn register_predicate_obligations(
62         &mut self,
63         infcx: &InferCtxt<'_, 'tcx>,
64         obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
65     );
66 }
67
68 impl<T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
69     fn register_predicate_obligations(
70         &mut self,
71         infcx: &InferCtxt<'_, 'tcx>,
72         obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
73     ) {
74         for obligation in obligations {
75             self.register_predicate_obligation(infcx, obligation);
76         }
77     }
78 }
79
80 impl dyn TraitEngine<'tcx> {
81     pub fn new(tcx: TyCtxt<'tcx>) -> Box<Self> {
82         if tcx.sess.opts.debugging_opts.chalk {
83             Box::new(ChalkFulfillmentContext::new())
84         } else {
85             Box::new(FulfillmentContext::new())
86         }
87     }
88 }