use crate::infer::InferCtxt;
use crate::traits::query::NoSolution;
use crate::traits::{
- ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, ObligationCause,
- PredicateObligation, SelectionError, TraitEngine,
+ ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, PredicateObligation,
+ SelectionError, TraitEngine,
};
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
-use rustc_middle::ty::{self, Ty, TypeVisitable};
+use rustc_middle::ty::{self, TypeVisitable};
pub struct FulfillmentContext<'tcx> {
obligations: FxIndexSet<PredicateObligation<'tcx>>,
relationships: FxHashMap<ty::TyVid, ty::FoundRelationships>,
+
+ usable_in_snapshot: bool,
}
impl FulfillmentContext<'_> {
- pub(crate) fn new() -> Self {
+ pub(super) fn new() -> Self {
FulfillmentContext {
obligations: FxIndexSet::default(),
relationships: FxHashMap::default(),
+ usable_in_snapshot: false,
}
}
-}
-impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
- fn normalize_projection_type(
- &mut self,
- infcx: &InferCtxt<'tcx>,
- _param_env: ty::ParamEnv<'tcx>,
- projection_ty: ty::ProjectionTy<'tcx>,
- _cause: ObligationCause<'tcx>,
- ) -> Ty<'tcx> {
- infcx.tcx.mk_ty(ty::Projection(projection_ty))
+ pub(crate) fn new_in_snapshot() -> Self {
+ FulfillmentContext { usable_in_snapshot: true, ..Self::new() }
}
+}
+impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
fn register_predicate_obligation(
&mut self,
infcx: &InferCtxt<'tcx>,
obligation: PredicateObligation<'tcx>,
) {
- assert!(!infcx.is_in_snapshot());
+ if !self.usable_in_snapshot {
+ assert!(!infcx.is_in_snapshot());
+ }
let obligation = infcx.resolve_vars_if_possible(obligation);
super::relationships::update(self, infcx, &obligation);
}
fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec<FulfillmentError<'tcx>> {
- assert!(!infcx.is_in_snapshot());
+ if !self.usable_in_snapshot {
+ assert!(!infcx.is_in_snapshot());
+ }
let mut errors = Vec::new();
let mut next_round = FxIndexSet::default();