2020-02-22 11:44:18 +01:00
|
|
|
use crate::infer::InferCtxt;
|
|
|
|
use crate::traits::Obligation;
|
|
|
|
use rustc_hir::def_id::DefId;
|
2021-12-12 12:34:46 +08:00
|
|
|
use rustc_middle::ty::{self, ToPredicate, Ty};
|
2020-02-22 11:44:18 +01:00
|
|
|
|
|
|
|
use super::FulfillmentError;
|
|
|
|
use super::{ObligationCause, PredicateObligation};
|
|
|
|
|
|
|
|
pub trait TraitEngine<'tcx>: 'tcx {
|
|
|
|
/// Requires that `ty` must implement the trait with `def_id` in
|
|
|
|
/// the given environment. This trait must not have any type
|
|
|
|
/// parameters (except for `Self`).
|
|
|
|
fn register_bound(
|
|
|
|
&mut self,
|
2022-09-09 13:01:06 -05:00
|
|
|
infcx: &InferCtxt<'tcx>,
|
2020-02-22 11:44:18 +01:00
|
|
|
param_env: ty::ParamEnv<'tcx>,
|
|
|
|
ty: Ty<'tcx>,
|
|
|
|
def_id: DefId,
|
|
|
|
cause: ObligationCause<'tcx>,
|
|
|
|
) {
|
2023-04-25 16:07:48 +00:00
|
|
|
let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
|
2020-02-22 11:44:18 +01:00
|
|
|
self.register_predicate_obligation(
|
|
|
|
infcx,
|
|
|
|
Obligation {
|
|
|
|
cause,
|
|
|
|
recursion_depth: 0,
|
|
|
|
param_env,
|
2023-07-29 08:20:25 +00:00
|
|
|
predicate: ty::Binder::dummy(trait_ref).to_predicate(infcx.tcx),
|
2020-02-22 11:44:18 +01:00
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn register_predicate_obligation(
|
|
|
|
&mut self,
|
2022-09-09 13:01:06 -05:00
|
|
|
infcx: &InferCtxt<'tcx>,
|
2020-02-22 11:44:18 +01:00
|
|
|
obligation: PredicateObligation<'tcx>,
|
|
|
|
);
|
|
|
|
|
2023-04-12 10:31:41 +02:00
|
|
|
#[must_use]
|
2022-09-09 13:01:06 -05:00
|
|
|
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
|
2021-07-26 10:52:17 +08:00
|
|
|
|
2023-04-09 04:29:43 +00:00
|
|
|
fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>>;
|
2022-09-28 18:16:23 +02:00
|
|
|
|
2020-02-22 11:44:18 +01:00
|
|
|
fn pending_obligations(&self) -> Vec<PredicateObligation<'tcx>>;
|
2022-10-01 15:57:22 +02:00
|
|
|
|
|
|
|
/// Among all pending obligations, collect those are stalled on a inference variable which has
|
2023-01-21 10:12:11 +00:00
|
|
|
/// changed since the last call to `select_where_possible`. Those obligations are marked as
|
2022-10-01 15:57:22 +02:00
|
|
|
/// successful and returned.
|
|
|
|
fn drain_unstalled_obligations(
|
|
|
|
&mut self,
|
|
|
|
infcx: &InferCtxt<'tcx>,
|
|
|
|
) -> Vec<PredicateObligation<'tcx>>;
|
2020-02-22 11:44:18 +01:00
|
|
|
}
|
|
|
|
|
2024-02-14 17:18:56 +00:00
|
|
|
#[extension(pub trait TraitEngineExt<'tcx>)]
|
|
|
|
impl<'tcx, T: ?Sized + TraitEngine<'tcx>> T {
|
2020-02-22 11:44:18 +01:00
|
|
|
fn register_predicate_obligations(
|
|
|
|
&mut self,
|
2022-09-09 13:01:06 -05:00
|
|
|
infcx: &InferCtxt<'tcx>,
|
2020-02-22 11:44:18 +01:00
|
|
|
obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>,
|
|
|
|
) {
|
|
|
|
for obligation in obligations {
|
|
|
|
self.register_predicate_obligation(infcx, obligation);
|
|
|
|
}
|
|
|
|
}
|
2022-09-28 18:16:23 +02:00
|
|
|
|
|
|
|
fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
|
|
|
|
let errors = self.select_where_possible(infcx);
|
|
|
|
if !errors.is_empty() {
|
|
|
|
return errors;
|
|
|
|
}
|
|
|
|
|
2023-04-09 04:29:43 +00:00
|
|
|
self.collect_remaining_errors(infcx)
|
2022-09-28 18:16:23 +02:00
|
|
|
}
|
2020-02-22 11:44:18 +01:00
|
|
|
}
|