|  | use std::fmt::Debug; | 
|  |  | 
|  | use rustc_hir::def_id::DefId; | 
|  | use rustc_middle::ty::{self, Ty, Upcast}; | 
|  |  | 
|  | use super::{ObligationCause, PredicateObligation, PredicateObligations}; | 
|  | use crate::infer::InferCtxt; | 
|  | use crate::traits::Obligation; | 
|  |  | 
|  | /// A trait error with most of its information removed. This is the error | 
|  | /// returned by an `ObligationCtxt` by default, and suitable if you just | 
|  | /// want to see if a predicate holds, and don't particularly care about the | 
|  | /// error itself (except for if it's an ambiguity or true error). | 
|  | /// | 
|  | /// use `ObligationCtxt::new_with_diagnostics` to get a `FulfillmentError`. | 
|  | #[derive(Clone, Debug)] | 
|  | pub enum ScrubbedTraitError<'tcx> { | 
|  | /// A real error. This goal definitely does not hold. | 
|  | TrueError, | 
|  | /// An ambiguity. This goal may hold if further inference is done. | 
|  | Ambiguity, | 
|  | /// An old-solver-style cycle error, which will fatal. This is not | 
|  | /// returned by the new solver. | 
|  | Cycle(PredicateObligations<'tcx>), | 
|  | } | 
|  |  | 
|  | impl<'tcx> ScrubbedTraitError<'tcx> { | 
|  | pub fn is_true_error(&self) -> bool { | 
|  | match self { | 
|  | ScrubbedTraitError::TrueError => true, | 
|  | ScrubbedTraitError::Ambiguity | ScrubbedTraitError::Cycle(_) => false, | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | pub trait TraitEngine<'tcx, E: '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, | 
|  | infcx: &InferCtxt<'tcx>, | 
|  | param_env: ty::ParamEnv<'tcx>, | 
|  | ty: Ty<'tcx>, | 
|  | def_id: DefId, | 
|  | cause: ObligationCause<'tcx>, | 
|  | ) { | 
|  | let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]); | 
|  | self.register_predicate_obligation( | 
|  | infcx, | 
|  | Obligation { | 
|  | cause, | 
|  | recursion_depth: 0, | 
|  | param_env, | 
|  | predicate: trait_ref.upcast(infcx.tcx), | 
|  | }, | 
|  | ); | 
|  | } | 
|  |  | 
|  | fn register_predicate_obligation( | 
|  | &mut self, | 
|  | infcx: &InferCtxt<'tcx>, | 
|  | obligation: PredicateObligation<'tcx>, | 
|  | ); | 
|  |  | 
|  | fn register_predicate_obligations( | 
|  | &mut self, | 
|  | infcx: &InferCtxt<'tcx>, | 
|  | obligations: PredicateObligations<'tcx>, | 
|  | ) { | 
|  | for obligation in obligations { | 
|  | self.register_predicate_obligation(infcx, obligation); | 
|  | } | 
|  | } | 
|  |  | 
|  | #[must_use] | 
|  | fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E>; | 
|  |  | 
|  | fn collect_remaining_errors(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E>; | 
|  |  | 
|  | #[must_use] | 
|  | fn select_all_or_error(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<E> { | 
|  | let errors = self.select_where_possible(infcx); | 
|  | if !errors.is_empty() { | 
|  | return errors; | 
|  | } | 
|  |  | 
|  | self.collect_remaining_errors(infcx) | 
|  | } | 
|  |  | 
|  | fn has_pending_obligations(&self) -> bool; | 
|  |  | 
|  | fn pending_obligations(&self) -> PredicateObligations<'tcx>; | 
|  |  | 
|  | /// Among all pending obligations, collect those are stalled on a inference variable which has | 
|  | /// changed since the last call to `select_where_possible`. Those obligations are marked as | 
|  | /// successful and returned. | 
|  | fn drain_stalled_obligations_for_coroutines( | 
|  | &mut self, | 
|  | infcx: &InferCtxt<'tcx>, | 
|  | ) -> PredicateObligations<'tcx>; | 
|  | } | 
|  |  | 
|  | pub trait FromSolverError<'tcx, E>: Debug + 'tcx { | 
|  | fn from_solver_error(infcx: &InferCtxt<'tcx>, error: E) -> Self; | 
|  | } |