Remove fully_normalize

This commit is contained in:
Michael Goulet 2024-07-11 19:15:00 -04:00
parent 0c81f94b9a
commit 2c8bbeebf1
4 changed files with 38 additions and 76 deletions

View file

@ -271,13 +271,14 @@ fn do_normalize_predicates<'tcx>(
// them here too, and we will remove this function when
// we move over to lazy normalization *anyway*.
let infcx = tcx.infer_ctxt().ignoring_regions().build();
let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) {
Ok(predicates) => predicates,
Err(errors) => {
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
return Err(reported);
}
};
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
let predicates = ocx.normalize(&cause, elaborated_env, predicates);
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
return Err(reported);
}
debug!("do_normalize_predicates: normalized predicates = {:?}", predicates);
@ -465,37 +466,6 @@ pub fn normalize_param_env_or_error<'tcx>(
ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal())
}
/// Normalize a type and process all resulting obligations, returning any errors.
///
/// FIXME(-Znext-solver): This should be replaced by `At::deeply_normalize`
/// which has the same behavior with the new solver. Because using a separate
/// fulfillment context worsens caching in the old solver, `At::deeply_normalize`
/// is still lazy with the old solver as it otherwise negatively impacts perf.
#[instrument(skip_all)]
pub fn fully_normalize<'tcx, T>(
infcx: &InferCtxt<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
value: T,
) -> Result<T, Vec<FulfillmentError<'tcx>>>
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
let ocx = ObligationCtxt::new_with_diagnostics(infcx);
debug!(?value);
let normalized_value = ocx.normalize(&cause, param_env, value);
debug!(?normalized_value);
debug!("select_all_or_error start");
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
return Err(errors);
}
debug!("select_all_or_error complete");
let resolved_value = infcx.resolve_vars_if_possible(normalized_value);
debug!(?resolved_value);
Ok(resolved_value)
}
/// Normalizes the predicates and checks whether they hold in an empty environment. If this
/// returns true, then either normalize encountered an error or one of the predicates did not
/// hold. Used when creating vtables to check for unsatisfiable methods.

View file

@ -42,11 +42,9 @@ impl<'tcx> At<'_, 'tcx> {
/// same goals in both a temporary and the shared context which negatively impacts
/// performance as these don't share caching.
///
/// FIXME(-Znext-solver): This has the same behavior as `traits::fully_normalize`
/// in the new solver, but because of performance reasons, we currently reuse an
/// existing fulfillment context in the old solver. Once we also eagerly prove goals with
/// the old solver or have removed the old solver, remove `traits::fully_normalize` and
/// rename this function to `At::fully_normalize`.
/// FIXME(-Znext-solver): For performance reasons, we currently reuse an existing
/// fulfillment context in the old solver. Once we have removed the old solver, we
/// can remove the `fulfill_cx` parameter on this function.
fn deeply_normalize<T, E>(
self,
value: T,

View file

@ -18,9 +18,7 @@ use crate::error_reporting::traits::to_pretty_impl_header;
use crate::errors::NegativePositiveConflict;
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::{
self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt,
};
use crate::traits::{coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt};
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{codes::*, Diag, EmissionGuarantee};
use rustc_hir::def_id::{DefId, LocalDefId};
@ -219,19 +217,17 @@ fn fulfill_implication<'tcx>(
param_env, source_trait_ref, target_impl
);
let source_trait_ref =
match traits::fully_normalize(infcx, ObligationCause::dummy(), param_env, source_trait_ref)
{
Ok(source_trait_ref) => source_trait_ref,
Err(_errors) => {
infcx.dcx().span_delayed_bug(
infcx.tcx.def_span(source_impl),
format!("failed to fully normalize {source_trait_ref}"),
);
source_trait_ref
}
};
let ocx = ObligationCtxt::new(infcx);
let source_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, source_trait_ref);
if !ocx.select_all_or_error().is_empty() {
infcx.dcx().span_delayed_bug(
infcx.tcx.def_span(source_impl),
format!("failed to fully normalize {source_trait_ref}"),
);
}
let source_trait_ref = infcx.resolve_vars_if_possible(source_trait_ref);
let source_trait = ImplSubject::Trait(source_trait_ref);
let selcx = SelectionContext::new(infcx);
@ -253,9 +249,6 @@ fn fulfill_implication<'tcx>(
return Err(());
};
// Needs to be `in_snapshot` because this function is used to rebase
// generic parameters, which may happen inside of a select within a probe.
let ocx = ObligationCtxt::new(infcx);
// attempt to prove all of the predicates for impl2 given those for impl1
// (which are packed up in penv)
ocx.register_obligations(obligations.chain(more_obligations));