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}
;
6 use super::FulfillmentError
;
7 use super::{ObligationCause, PredicateObligation}
;
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`).
15 infcx
: &InferCtxt
<'tcx
>,
16 param_env
: ty
::ParamEnv
<'tcx
>,
19 cause
: ObligationCause
<'tcx
>,
21 let trait_ref
= ty
::TraitRef
::new(infcx
.tcx
, def_id
, [ty
]);
22 self.register_predicate_obligation(
28 predicate
: ty
::Binder
::dummy(trait_ref
).to_predicate(infcx
.tcx
),
33 fn register_predicate_obligation(
35 infcx
: &InferCtxt
<'tcx
>,
36 obligation
: PredicateObligation
<'tcx
>,
40 fn select_where_possible(&mut self, infcx
: &InferCtxt
<'tcx
>) -> Vec
<FulfillmentError
<'tcx
>>;
42 fn collect_remaining_errors(&mut self, infcx
: &InferCtxt
<'tcx
>) -> Vec
<FulfillmentError
<'tcx
>>;
44 fn pending_obligations(&self) -> Vec
<PredicateObligation
<'tcx
>>;
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(
51 infcx
: &InferCtxt
<'tcx
>,
52 ) -> Vec
<PredicateObligation
<'tcx
>>;
55 pub trait TraitEngineExt
<'tcx
> {
56 fn register_predicate_obligations(
58 infcx
: &InferCtxt
<'tcx
>,
59 obligations
: impl IntoIterator
<Item
= PredicateObligation
<'tcx
>>,
63 fn select_all_or_error(&mut self, infcx
: &InferCtxt
<'tcx
>) -> Vec
<FulfillmentError
<'tcx
>>;
66 impl<'tcx
, T
: ?Sized
+ TraitEngine
<'tcx
>> TraitEngineExt
<'tcx
> for T
{
67 fn register_predicate_obligations(
69 infcx
: &InferCtxt
<'tcx
>,
70 obligations
: impl IntoIterator
<Item
= PredicateObligation
<'tcx
>>,
72 for obligation
in obligations
{
73 self.register_predicate_obligation(infcx
, obligation
);
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() {
83 self.collect_remaining_errors(infcx
)