pub(super) struct InProgress;
pub trait NormalizeExt<'tcx> {
+ /// Normalize a value using the `AssocTypeNormalizer`.
+ ///
+ /// This normalization should be used when the type contains inference variables or the
+ /// projection may be fallible.
fn normalize<T: TypeFoldable<'tcx>>(&self, t: T) -> InferOk<'tcx, T>;
}
fn normalize<T: TypeFoldable<'tcx>>(&self, value: T) -> InferOk<'tcx, T> {
let mut selcx = SelectionContext::new(self.infcx);
let Normalized { value, obligations } =
- normalize(&mut selcx, self.param_env, self.cause.clone(), value);
+ normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
InferOk { value, obligations }
}
}
}
}
-/// Normalizes any associated type projections in `value`, replacing
-/// them with a fully resolved type where possible. The return value
-/// combines the normalized result and any additional obligations that
-/// were incurred as result.
-pub(crate) fn normalize<'a, 'b, 'tcx, T>(
- selcx: &'a mut SelectionContext<'b, 'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- cause: ObligationCause<'tcx>,
- value: T,
-) -> Normalized<'tcx, T>
-where
- T: TypeFoldable<'tcx>,
-{
- let mut obligations = Vec::new();
- let value = normalize_to(selcx, param_env, cause, value, &mut obligations);
- Normalized { value, obligations }
-}
-
-pub(crate) fn normalize_to<'a, 'b, 'tcx, T>(
- selcx: &'a mut SelectionContext<'b, 'tcx>,
- param_env: ty::ParamEnv<'tcx>,
- cause: ObligationCause<'tcx>,
- value: T,
- obligations: &mut Vec<PredicateObligation<'tcx>>,
-) -> T
-where
- T: TypeFoldable<'tcx>,
-{
- normalize_with_depth_to(selcx, param_env, cause, 0, value, obligations)
-}
-
/// As `normalize`, but with a custom depth.
pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>(
selcx: &'a mut SelectionContext<'b, 'tcx>,
Reveal::All => {
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
- let obligation = Obligation::with_depth(
- self.tcx(),
- self.cause.clone(),
- recursion_limit.0,
- self.param_env,
- ty,
+ self.selcx.infcx.err_ctxt().report_overflow_error(
+ &ty,
+ self.cause.span,
+ true,
+ |_| {},
);
- self.selcx.infcx.err_ctxt().report_overflow_error(&obligation, true);
}
let substs = substs.fold_with(self);
},
));
- let ty = super::normalize_to(
+ let ty = normalize_with_depth_to(
selcx,
obligation.param_env,
cause.clone(),
+ obligation.recursion_depth + 1,
tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
.map_bound(|tys| {
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
nested: &mut Vec<PredicateObligation<'tcx>>,
) {
let tcx = selcx.tcx();
- for predicate in tcx
+ let own = tcx
.predicates_of(obligation.predicate.item_def_id)
- .instantiate_own(tcx, obligation.predicate.substs)
- .predicates
- {
+ .instantiate_own(tcx, obligation.predicate.substs);
+ for (predicate, span) in std::iter::zip(own.predicates, own.spans) {
let normalized = normalize_with_depth_to(
selcx,
obligation.param_env,
predicate,
nested,
);
+
+ let nested_cause = if matches!(
+ obligation.cause.code(),
+ super::CompareImplItemObligation { .. }
+ | super::CheckAssociatedTypeBounds { .. }
+ | super::AscribeUserTypeProvePredicate(..)
+ ) {
+ obligation.cause.clone()
+ } else if span.is_dummy() {
+ ObligationCause::new(
+ obligation.cause.span,
+ obligation.cause.body_id,
+ super::ItemObligation(obligation.predicate.item_def_id),
+ )
+ } else {
+ ObligationCause::new(
+ obligation.cause.span,
+ obligation.cause.body_id,
+ super::BindingObligation(obligation.predicate.item_def_id, span),
+ )
+ };
nested.push(Obligation::with_depth(
tcx,
- obligation.cause.clone(),
+ nested_cause,
obligation.recursion_depth + 1,
obligation.param_env,
normalized,