1
Fork 0

deeply_normalize pass in fulfill cx for old solver

This commit is contained in:
lcnr 2023-06-29 14:17:54 +02:00
parent 5378f07d64
commit a2dfed6711
2 changed files with 15 additions and 12 deletions

View file

@ -229,7 +229,11 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
// implied_bounds.insert(ty); // implied_bounds.insert(ty);
let cause = ObligationCause::misc(span, def_id); let cause = ObligationCause::misc(span, def_id);
match self.infcx.at(&cause, param_env).deeply_normalize(ty) { match self
.infcx
.at(&cause, param_env)
.deeply_normalize(ty, &mut **self.engine.borrow_mut())
{
// Insert well-formed types, ignoring duplicates. // Insert well-formed types, ignoring duplicates.
Ok(normalized) => drop(implied_bounds.insert(normalized)), Ok(normalized) => drop(implied_bounds.insert(normalized)),
Err(normalization_errors) => errors.extend(normalization_errors), Err(normalization_errors) => errors.extend(normalization_errors),

View file

@ -20,7 +20,6 @@ use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime};
use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::error_reporting::TypeErrCtxtExt as _;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::select::ProjectionMatchesProjection; use crate::traits::select::ProjectionMatchesProjection;
use crate::traits::TraitEngineExt as _;
use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::sso::SsoHashSet;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
@ -32,7 +31,6 @@ use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::traits::FulfillmentError; use rustc_infer::traits::FulfillmentError;
use rustc_infer::traits::ObligationCauseCode; use rustc_infer::traits::ObligationCauseCode;
use rustc_infer::traits::TraitEngine; use rustc_infer::traits::TraitEngine;
use rustc_infer::traits::TraitEngineExt as _;
use rustc_middle::traits::select::OverflowError; use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
@ -59,17 +57,17 @@ pub trait NormalizeExt<'tcx> {
fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>; fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>;
/// Deeply normalizes `value`, replacing all aliases which can by normalized in /// Deeply normalizes `value`, replacing all aliases which can by normalized in
/// the current environment. Unlike other normalization routines, this errors /// the current environment. In the new solver this errors in case normalization
/// in case normalization fails or is ambiguous. /// fails or is ambiguous. This only normalize opaque types with `Reveal::All`.
/// ///
/// In the old solver this simply uses `normalize` and errors in /// In the old solver this simply uses `normalizes` and adds the nested obligations
/// case of ambiguity. The new solver only normalizes in this function and /// to the `fulfill_cx`. This is necessary as we otherwise end up recomputing the
/// `normalize` is a noop. /// same goals in both a temporary and the shared context which negatively impacts
/// /// performance as these don't share caching.
/// This only normalize opaque types with `Reveal::All`.
fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>( fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
self, self,
value: T, value: T,
fulfill_cx: &mut dyn TraitEngine<'tcx>,
) -> Result<T, Vec<FulfillmentError<'tcx>>>; ) -> Result<T, Vec<FulfillmentError<'tcx>>>;
} }
@ -88,15 +86,16 @@ impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>( fn deeply_normalize<T: TypeFoldable<TyCtxt<'tcx>>>(
self, self,
value: T, value: T,
fulfill_cx: &mut dyn TraitEngine<'tcx>,
) -> Result<T, Vec<FulfillmentError<'tcx>>> { ) -> Result<T, Vec<FulfillmentError<'tcx>>> {
if self.infcx.next_trait_solver() { if self.infcx.next_trait_solver() {
crate::solve::deeply_normalize(self, value) crate::solve::deeply_normalize(self, value)
} else { } else {
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(&self.infcx);
let value = self let value = self
.normalize(value) .normalize(value)
.into_value_registering_obligations(self.infcx, &mut *fulfill_cx); .into_value_registering_obligations(self.infcx, &mut *fulfill_cx);
let errors = fulfill_cx.select_all_or_error(self.infcx); let errors = fulfill_cx.select_where_possible(self.infcx);
let value = self.infcx.resolve_vars_if_possible(value);
if errors.is_empty() { Ok(value) } else { Err(errors) } if errors.is_empty() { Ok(value) } else { Err(errors) }
} }
} }