1
Fork 0

Assert that obligations are empty before deeply normalizing

This commit is contained in:
Michael Goulet 2024-11-27 21:27:37 +00:00
parent abfa5c1dca
commit 398fd901d5
12 changed files with 37 additions and 25 deletions

View file

@ -199,6 +199,10 @@ where
errors
}
fn has_pending_obligations(&self) -> bool {
!self.obligations.pending.is_empty() || !self.obligations.overflowed.is_empty()
}
fn pending_obligations(&self) -> PredicateObligations<'tcx> {
self.obligations.clone_pending()
}

View file

@ -213,6 +213,10 @@ where
}
}
fn has_pending_obligations(&self) -> bool {
self.predicates.has_pending_obligations()
}
fn pending_obligations(&self) -> PredicateObligations<'tcx> {
self.predicates.map_pending_obligations(|o| o.obligation.clone())
}

View file

@ -7,6 +7,7 @@ use rustc_infer::traits::{
FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine,
};
use rustc_macros::extension;
use rustc_middle::span_bug;
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt,
@ -63,6 +64,14 @@ impl<'tcx> At<'_, 'tcx> {
if self.infcx.next_trait_solver() {
crate::solve::deeply_normalize(self, value)
} else {
if fulfill_cx.has_pending_obligations() {
let pending_obligations = fulfill_cx.pending_obligations();
span_bug!(
pending_obligations[0].cause.span,
"deeply_normalize should not be called with pending obligations: \
{pending_obligations:#?}"
);
}
let value = self
.normalize(value)
.into_value_registering_obligations(self.infcx, &mut *fulfill_cx);

View file

@ -60,6 +60,9 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
ty: Ty<'tcx>,
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
let normalize_op = |ty| -> Result<_, NoSolution> {
// We must normalize the type so we can compute the right outlives components.
// for example, if we have some constrained param type like `T: Trait<Out = U>`,
// and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`.
let ty = ocx
.deeply_normalize(&ObligationCause::dummy(), param_env, ty)
.map_err(|_| NoSolution)?;