From 02b64c5d2689fad8360d83f3bcd58f5dbbd2f303 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 1 Dec 2022 18:59:58 +0000 Subject: [PATCH] Document normalization methods on At --- .../src/traits/coherence.rs | 10 +++-- .../rustc_trait_selection/src/traits/mod.rs | 1 - .../src/traits/project.rs | 40 ++++--------------- .../src/traits/query/normalize.rs | 7 ++++ 4 files changed, 20 insertions(+), 38 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 99724fb28db..899e30275a0 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -11,8 +11,8 @@ use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::util::impl_subject_and_oblig; use crate::traits::SkipLeakCheck; use crate::traits::{ - self, Normalized, Obligation, ObligationCause, ObligationCtxt, PredicateObligation, - PredicateObligations, SelectionContext, + self, Obligation, ObligationCause, ObligationCtxt, PredicateObligation, PredicateObligations, + SelectionContext, }; use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Diagnostic; @@ -30,6 +30,8 @@ use std::fmt::Debug; use std::iter; use std::ops::ControlFlow; +use super::NormalizeExt; + /// Whether we do the orphan check relative to this crate or /// to some remote crate. #[derive(Copy, Clone, Debug)] @@ -128,8 +130,8 @@ fn with_fresh_ty_vars<'cx, 'tcx>( predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates, }; - let Normalized { value: mut header, obligations } = - traits::normalize(selcx, param_env, ObligationCause::dummy(), header); + let InferOk { value: mut header, obligations } = + selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(header); header.predicates.extend(obligations.into_iter().map(|o| o.predicate)); header diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 371367f0deb..c6818a4e57d 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -56,7 +56,6 @@ pub use self::object_safety::astconv_object_safety_violations; pub use self::object_safety::is_vtable_safe_method; pub use self::object_safety::MethodViolationCode; pub use self::object_safety::ObjectSafetyViolation; -pub(crate) use self::project::{normalize, normalize_to}; pub use self::project::{normalize_projection_type, NormalizeExt}; pub use self::select::{EvaluationCache, SelectionCache, SelectionContext}; pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError}; diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 113803cd179..051660be9c4 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -50,6 +50,10 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>> 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>(&self, t: T) -> InferOk<'tcx, T>; } @@ -57,7 +61,7 @@ impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> { fn normalize>(&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 } } } @@ -303,37 +307,6 @@ fn project_and_unify_type<'cx, 'tcx>( } } -/// 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>, -) -> 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>, @@ -2324,10 +2297,11 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( }, )); - 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]) diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 1aed6630870..f899321fc01 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -23,6 +23,13 @@ use super::NoSolution; pub use rustc_middle::traits::query::NormalizationResult; pub trait QueryNormalizeExt<'tcx> { + /// Normalize a value using the `QueryNormalizer`. + /// + /// This normalization should *only* be used when the projection does not + /// have possible ambiguity or may not be well-formed. + /// + /// After codegen, when lifetimes do not matter, it is preferable to instead + /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure. fn query_normalize(&self, value: T) -> Result, NoSolution> where T: TypeFoldable<'tcx>;