]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_infer/src/traits/engine.rs
New upstream version 1.73.0+dfsg1
[rustc.git] / compiler / rustc_infer / src / traits / engine.rs
1 use crate::infer::InferCtxt;
2 use crate::traits::Obligation;
3 use rustc_hir::def_id::DefId;
4 use rustc_middle::ty::{self, ToPredicate, Ty};
5
6 use super::FulfillmentError;
7 use super::{ObligationCause, PredicateObligation};
8
9 pub trait TraitEngine<'tcx>: 'tcx {
10 /// Requires that `ty` must implement the trait with `def_id` in
11 /// the given environment. This trait must not have any type
12 /// parameters (except for `Self`).
13 fn register_bound(
14 &mut self,
15 infcx: &InferCtxt<'tcx>,
16 param_env: ty::ParamEnv<'tcx>,
17 ty: Ty<'tcx>,
18 def_id: DefId,
19 cause: ObligationCause<'tcx>,
20 ) {
21 let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
22 self.register_predicate_obligation(
23 infcx,
24 Obligation {
25 cause,
26 recursion_depth: 0,
27 param_env,
28 predicate: ty::Binder::dummy(trait_ref).to_predicate(infcx.tcx),
29 },
30 );
31 }
32
33 fn register_predicate_obligation(
34 &mut self,
35 infcx: &InferCtxt<'tcx>,
36 obligation: PredicateObligation<'tcx>,
37 );
38
39 #[must_use]
40 fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
41
42 fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
43
44 fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
45
46 /// Among all pending obligations, collect those are stalled on a inference variable which has
47 /// changed since the last call to `select_where_possible`. Those obligations are marked as
48 /// successful and returned.
49 fn drain_unstalled_obligations(
50 &mut self,
51 infcx: &InferCtxt<'tcx>,
52 ) -> Vec<PredicateObligation<'tcx>>;
53 }
54
55 pub trait TraitEngineExt<'tcx> {
56 fn register_predicate_obligations(
57 &mut self,
58 infcx: &InferCtxt<'tcx>,
59 obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
60 );
61
62 #[must_use]
63 fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
64 }
65
66 impl<'tcx, T: ?Sized + TraitEngine<'tcx>> TraitEngineExt<'tcx> for T {
67 fn register_predicate_obligations(
68 &mut self,
69 infcx: &InferCtxt<'tcx>,
70 obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
71 ) {
72 for obligation in obligations {
73 self.register_predicate_obligation(infcx, obligation);
74 }
75 }
76
77 fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
78 let errors = self.select_where_possible(infcx);
79 if !errors.is_empty() {
80 return errors;
81 }
82
83 self.collect_remaining_errors(infcx)
84 }
85 }