]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_infer/src/traits/engine.rs
Rollup merge of #89922 - JohnTitor:update-e0637, r=jackh726
[rust.git] / compiler / rustc_infer / src / traits / engine.rs
1 use crate::infer::InferCtxt;
2 use crate::traits::Obligation;
3 use rustc_data_structures::fx::FxHashMap;
4 use rustc_hir as hir;
5 use rustc_hir::def_id::DefId;
6 use rustc_middle::ty::{self, ToPredicate, Ty, WithConstness};
7
8 use super::FulfillmentError;
9 use super::{ObligationCause, PredicateObligation};
10
11 pub trait TraitEngine<'tcx>: 'tcx {
12     fn normalize_projection_type(
13         &mut self,
14         infcx: &InferCtxt<'_, 'tcx>,
15         param_env: ty::ParamEnv<'tcx>,
16         projection_ty: ty::ProjectionTy<'tcx>,
17         cause: ObligationCause<'tcx>,
18     ) -> Ty<'tcx>;
19
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`).
23     fn register_bound(
24         &mut self,
25         infcx: &InferCtxt<'_, 'tcx>,
26         param_env: ty::ParamEnv<'tcx>,
27         ty: Ty<'tcx>,
28         def_id: DefId,
29         cause: ObligationCause<'tcx>,
30     ) {
31         let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) };
32         self.register_predicate_obligation(
33             infcx,
34             Obligation {
35                 cause,
36                 recursion_depth: 0,
37                 param_env,
38                 predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx),
39             },
40         );
41     }
42
43     fn register_predicate_obligation(
44         &mut self,
45         infcx: &InferCtxt<'_, 'tcx>,
46         obligation: PredicateObligation<'tcx>,
47     );
48
49     fn select_all_or_error(
50         &mut self,
51         infcx: &InferCtxt<'_, 'tcx>,
52     ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
53
54     fn select_all_with_constness_or_error(
55         &mut self,
56         infcx: &InferCtxt<'_, 'tcx>,
57         _constness: hir::Constness,
58     ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
59         self.select_all_or_error(infcx)
60     }
61
62     fn select_where_possible(
63         &mut self,
64         infcx: &InferCtxt<'_, 'tcx>,
65     ) -> Result<(), Vec<FulfillmentError<'tcx>>>;
66
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(
69         &mut self,
70         infcx: &InferCtxt<'_, 'tcx>,
71         _constness: hir::Constness,
72     ) -> Result<(), Vec<FulfillmentError<'tcx>>> {
73         self.select_where_possible(infcx)
74     }
75
76     fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
77
78     fn relationships(&mut self) -> &mut FxHashMap<ty::TyVid, ty::FoundRelationships>;
79 }
80
81 pub trait TraitEngineExt<'tcx> {
82     fn register_predicate_obligations(
83         &mut self,
84         infcx: &InferCtxt<'_, 'tcx>,
85         obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
86     );
87 }
88
89 impl<T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
90     fn register_predicate_obligations(
91         &mut self,
92         infcx: &InferCtxt<'_, 'tcx>,
93         obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
94     ) {
95         for obligation in obligations {
96             self.register_predicate_obligation(infcx, obligation);
97         }
98     }
99 }