X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_trait_selection%2Fsrc%2Ftraits%2Fproject.rs;h=051660be9c474abb77ada510476f05f55426dc14;hb=f4643f59cb44725ccab9ced2bfb621d09a6e3682;hp=e33e89e9c5c3eeadc65ffa9fa1dc5cf53e75d2e8;hpb=581ca3e836083bfbb2da888809d3ea16a4440c94;p=rust.git diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index e33e89e9c5c..051660be9c4 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -27,6 +27,7 @@ use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; +use rustc_infer::infer::at::At; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::ImplSourceBuiltinData; use rustc_middle::traits::select::OverflowError; @@ -48,6 +49,23 @@ 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>; +} + +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_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value); + InferOk { value, obligations } + } +} + /// When attempting to resolve `::Name` ... #[derive(Debug)] pub enum ProjectionError<'tcx> { @@ -289,39 +307,8 @@ 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 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 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 fn normalize_with_depth<'a, 'b, 'tcx, T>( +pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, @@ -337,7 +324,7 @@ pub fn normalize_with_depth<'a, 'b, 'tcx, T>( } #[instrument(level = "info", skip(selcx, param_env, cause, obligations))] -pub fn normalize_with_depth_to<'a, 'b, 'tcx, T>( +pub(crate) fn normalize_with_depth_to<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, @@ -357,7 +344,7 @@ pub fn normalize_with_depth_to<'a, 'b, 'tcx, T>( } #[instrument(level = "info", skip(selcx, param_env, cause, obligations))] -pub fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>( +pub(crate) fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>( selcx: &'a mut SelectionContext<'b, 'tcx>, param_env: ty::ParamEnv<'tcx>, cause: ObligationCause<'tcx>, @@ -2310,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])