|  | use rustc_hir::def_id::LocalDefId; | 
|  | use rustc_infer::infer::outlives::env::OutlivesEnvironment; | 
|  | use rustc_infer::infer::{InferCtxt, RegionResolutionError}; | 
|  | use rustc_macros::extension; | 
|  | use rustc_middle::traits::ObligationCause; | 
|  | use rustc_middle::traits::query::NoSolution; | 
|  | use rustc_middle::ty::{self, Ty, elaborate}; | 
|  |  | 
|  | use crate::traits::ScrubbedTraitError; | 
|  | use crate::traits::outlives_bounds::InferCtxtExt; | 
|  |  | 
|  | #[extension(pub trait OutlivesEnvironmentBuildExt<'tcx>)] | 
|  | impl<'tcx> OutlivesEnvironment<'tcx> { | 
|  | fn new( | 
|  | infcx: &InferCtxt<'tcx>, | 
|  | body_id: LocalDefId, | 
|  | param_env: ty::ParamEnv<'tcx>, | 
|  | assumed_wf_tys: impl IntoIterator<Item = Ty<'tcx>>, | 
|  | ) -> Self { | 
|  | Self::new_with_implied_bounds_compat(infcx, body_id, param_env, assumed_wf_tys, false) | 
|  | } | 
|  |  | 
|  | fn new_with_implied_bounds_compat( | 
|  | infcx: &InferCtxt<'tcx>, | 
|  | body_id: LocalDefId, | 
|  | param_env: ty::ParamEnv<'tcx>, | 
|  | assumed_wf_tys: impl IntoIterator<Item = Ty<'tcx>>, | 
|  | disable_implied_bounds_hack: bool, | 
|  | ) -> Self { | 
|  | let mut bounds = vec![]; | 
|  |  | 
|  | for bound in param_env.caller_bounds() { | 
|  | if let Some(mut type_outlives) = bound.as_type_outlives_clause() { | 
|  | if infcx.next_trait_solver() { | 
|  | match crate::solve::deeply_normalize::<_, ScrubbedTraitError<'tcx>>( | 
|  | infcx.at(&ObligationCause::dummy(), param_env), | 
|  | type_outlives, | 
|  | ) { | 
|  | Ok(new) => type_outlives = new, | 
|  | Err(_) => { | 
|  | infcx.dcx().delayed_bug(format!("could not normalize `{bound}`")); | 
|  | } | 
|  | } | 
|  | } | 
|  | bounds.push(type_outlives); | 
|  | } | 
|  | } | 
|  |  | 
|  | // FIXME(-Znext-trait-solver): Normalize these. | 
|  | let higher_ranked_assumptions = infcx.take_registered_region_assumptions(); | 
|  | let higher_ranked_assumptions = | 
|  | elaborate::elaborate_outlives_assumptions(infcx.tcx, higher_ranked_assumptions); | 
|  |  | 
|  | // FIXME: This needs to be modified so that we normalize the known type | 
|  | // outlives obligations then elaborate them into their region/type components. | 
|  | // Otherwise, `<W<'a> as Mirror>::Assoc: 'b` will not imply `'a: 'b` even | 
|  | // if we can normalize `'a`. | 
|  | OutlivesEnvironment::from_normalized_bounds( | 
|  | param_env, | 
|  | bounds, | 
|  | infcx.implied_bounds_tys( | 
|  | body_id, | 
|  | param_env, | 
|  | assumed_wf_tys, | 
|  | disable_implied_bounds_hack, | 
|  | ), | 
|  | higher_ranked_assumptions, | 
|  | ) | 
|  | } | 
|  | } | 
|  |  | 
|  | #[extension(pub trait InferCtxtRegionExt<'tcx>)] | 
|  | impl<'tcx> InferCtxt<'tcx> { | 
|  | /// Resolve regions, using the deep normalizer to normalize any type-outlives | 
|  | /// obligations in the process. This is in `rustc_trait_selection` because | 
|  | /// we need to normalize. | 
|  | /// | 
|  | /// Prefer this method over `resolve_regions_with_normalize`, unless you are | 
|  | /// doing something specific for normalization. | 
|  | /// | 
|  | /// This function assumes that all infer variables are already constrained. | 
|  | fn resolve_regions( | 
|  | &self, | 
|  | body_id: LocalDefId, | 
|  | param_env: ty::ParamEnv<'tcx>, | 
|  | assumed_wf_tys: impl IntoIterator<Item = Ty<'tcx>>, | 
|  | ) -> Vec<RegionResolutionError<'tcx>> { | 
|  | self.resolve_regions_with_outlives_env(&OutlivesEnvironment::new( | 
|  | self, | 
|  | body_id, | 
|  | param_env, | 
|  | assumed_wf_tys, | 
|  | )) | 
|  | } | 
|  |  | 
|  | /// Don't call this directly unless you know what you're doing. | 
|  | fn resolve_regions_with_outlives_env( | 
|  | &self, | 
|  | outlives_env: &OutlivesEnvironment<'tcx>, | 
|  | ) -> Vec<RegionResolutionError<'tcx>> { | 
|  | self.resolve_regions_with_normalize(&outlives_env, |ty, origin| { | 
|  | let ty = self.resolve_vars_if_possible(ty); | 
|  |  | 
|  | if self.next_trait_solver() { | 
|  | crate::solve::deeply_normalize( | 
|  | self.at( | 
|  | &ObligationCause::dummy_with_span(origin.span()), | 
|  | outlives_env.param_env, | 
|  | ), | 
|  | ty, | 
|  | ) | 
|  | .map_err(|_: Vec<ScrubbedTraitError<'tcx>>| NoSolution) | 
|  | } else { | 
|  | Ok(ty) | 
|  | } | 
|  | }) | 
|  | } | 
|  | } |