Rollup merge of #133517 - compiler-errors:deep-norm, r=lcnr
Deeply normalize when computing implied outlives bounds
r? lcnr
Unfortunately resolving regions is still slightly scuffed (though in an unrelated way). Specifically, we should be normalizing our param-env outlives when constructing the `OutlivesEnv`; otherwise, these assumptions (dd2837ec5d/compiler/rustc_infer/src/infer/outlives/env.rs (L78)
) are not constructed correctly.
Let me know if you want us to track that somewhere.
This commit is contained in:
commit
68279097d4
13 changed files with 88 additions and 29 deletions
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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,10 +64,18 @@ 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);
|
||||
let errors = fulfill_cx.select_where_possible(self.infcx);
|
||||
let errors = fulfill_cx.select_all_or_error(self.infcx);
|
||||
let value = self.infcx.resolve_vars_if_possible(value);
|
||||
if errors.is_empty() { Ok(value) } else { Err(errors) }
|
||||
}
|
||||
|
|
|
@ -59,12 +59,16 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
|||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
|
||||
let normalize_op = |ty| {
|
||||
let ty = ocx.normalize(&ObligationCause::dummy(), param_env, ty);
|
||||
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)?;
|
||||
if !ocx.select_all_or_error().is_empty() {
|
||||
return Err(NoSolution);
|
||||
}
|
||||
let ty = ocx.infcx.resolve_vars_if_possible(ty);
|
||||
let ty = OpportunisticRegionResolver::new(&ocx.infcx).fold_ty(ty);
|
||||
Ok(ty)
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue