use std::cell::RefCell;
+use std::fmt::Debug;
use super::TraitEngine;
use super::{ChalkFulfillmentContext, FulfillmentContext};
use crate::infer::InferCtxtExt;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_infer::infer::at::ToTrace;
+use rustc_infer::infer::canonical::{
+ Canonical, CanonicalVarValues, CanonicalizedQueryResponse, QueryResponse,
+};
use rustc_infer::infer::{InferCtxt, InferOk};
+use rustc_infer::traits::query::Fallible;
use rustc_infer::traits::{
FulfillmentError, Obligation, ObligationCause, PredicateObligation, TraitEngineExt as _,
};
+use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::TypeFoldable;
/// Used if you want to have pleasant experience when dealing
/// with obligations outside of hir or mir typeck.
pub struct ObligationCtxt<'a, 'tcx> {
- pub infcx: &'a InferCtxt<'a, 'tcx>,
+ pub infcx: &'a InferCtxt<'tcx>,
engine: RefCell<Box<dyn TraitEngine<'tcx>>>,
}
impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
- pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
+ pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new(infcx.tcx)) }
}
- pub fn new_in_snapshot(infcx: &'a InferCtxt<'a, 'tcx>) -> Self {
+ pub fn new_in_snapshot(infcx: &'a InferCtxt<'tcx>) -> Self {
Self { infcx, engine: RefCell::new(<dyn TraitEngine<'_>>::new_in_snapshot(infcx.tcx)) }
}
self.register_infer_ok_obligations(infer_ok)
}
- pub fn equate_types(
+ pub fn eq<T: ToTrace<'tcx>>(
&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
- expected: Ty<'tcx>,
- actual: Ty<'tcx>,
+ expected: T,
+ actual: T,
) -> Result<(), TypeError<'tcx>> {
match self.infcx.at(cause, param_env).eq(expected, actual) {
Ok(InferOk { obligations, value: () }) => {
}
}
+ pub fn sup<T: ToTrace<'tcx>>(
+ &self,
+ cause: &ObligationCause<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
+ expected: T,
+ actual: T,
+ ) -> Result<(), TypeError<'tcx>> {
+ match self.infcx.at(cause, param_env).sup(expected, actual) {
+ Ok(InferOk { obligations, value: () }) => {
+ self.register_obligations(obligations);
+ Ok(())
+ }
+ Err(e) => Err(e),
+ }
+ }
+
pub fn select_all_or_error(&self) -> Vec<FulfillmentError<'tcx>> {
self.engine.borrow_mut().select_all_or_error(self.infcx)
}
}
implied_bounds
}
+
+ pub fn make_canonicalized_query_response<T>(
+ &self,
+ inference_vars: CanonicalVarValues<'tcx>,
+ answer: T,
+ ) -> Fallible<CanonicalizedQueryResponse<'tcx, T>>
+ where
+ T: Debug + TypeFoldable<'tcx>,
+ Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>,
+ {
+ self.infcx.make_canonicalized_query_response(
+ inference_vars,
+ answer,
+ &mut **self.engine.borrow_mut(),
+ )
+ }
}