include ParamEnv in projection cache key
diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs
index 31ceb23..c6ffba5 100644
--- a/compiler/rustc_infer/src/traits/project.rs
+++ b/compiler/rustc_infer/src/traits/project.rs
@@ -78,11 +78,12 @@
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct ProjectionCacheKey<'tcx> {
ty: ty::AliasTy<'tcx>,
+ param_env: ty::ParamEnv<'tcx>,
}
impl<'tcx> ProjectionCacheKey<'tcx> {
- pub fn new(ty: ty::AliasTy<'tcx>) -> Self {
- Self { ty }
+ pub fn new(ty: ty::AliasTy<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
+ Self { ty, param_env }
}
}
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index fbff783..8cd9f39 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -758,9 +758,9 @@
// no type variables present, can use evaluation for better caching.
// FIXME: consider caching errors too.
if self.selcx.infcx.predicate_must_hold_considering_regions(obligation) {
- if let Some(key) = ProjectionCacheKey::from_poly_projection_predicate(
+ if let Some(key) = ProjectionCacheKey::from_poly_projection_obligation(
&mut self.selcx,
- project_obligation.predicate,
+ &project_obligation,
) {
// If `predicate_must_hold_considering_regions` succeeds, then we've
// evaluated all sub-obligations. We can therefore mark the 'root'
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 67865bf..ca0b508 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -344,7 +344,7 @@
let use_cache = !selcx.is_intercrate();
let projection_ty = infcx.resolve_vars_if_possible(projection_ty);
- let cache_key = ProjectionCacheKey::new(projection_ty);
+ let cache_key = ProjectionCacheKey::new(projection_ty, param_env);
// FIXME(#20304) For now, I am caching here, which is good, but it
// means we don't capture the type variables that are created in
@@ -2105,27 +2105,28 @@
}
pub(crate) trait ProjectionCacheKeyExt<'cx, 'tcx>: Sized {
- fn from_poly_projection_predicate(
+ fn from_poly_projection_obligation(
selcx: &mut SelectionContext<'cx, 'tcx>,
- predicate: ty::PolyProjectionPredicate<'tcx>,
+ obligation: &PolyProjectionObligation<'tcx>,
) -> Option<Self>;
}
impl<'cx, 'tcx> ProjectionCacheKeyExt<'cx, 'tcx> for ProjectionCacheKey<'tcx> {
- fn from_poly_projection_predicate(
+ fn from_poly_projection_obligation(
selcx: &mut SelectionContext<'cx, 'tcx>,
- predicate: ty::PolyProjectionPredicate<'tcx>,
+ obligation: &PolyProjectionObligation<'tcx>,
) -> Option<Self> {
let infcx = selcx.infcx;
// We don't do cross-snapshot caching of obligations with escaping regions,
// so there's no cache key to use
- predicate.no_bound_vars().map(|predicate| {
+ obligation.predicate.no_bound_vars().map(|predicate| {
ProjectionCacheKey::new(
// We don't attempt to match up with a specific type-variable state
// from a specific call to `opt_normalize_projection_type` - if
// there's no precise match, the original cache entry is "stranded"
// anyway.
infcx.resolve_vars_if_possible(predicate.projection_ty),
+ obligation.param_env,
)
})
}
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 10370c7..fc12fed 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -815,7 +815,10 @@
// `EvaluatedToOkModuloRegions`), and skip re-evaluating the
// sub-obligations.
if let Some(key) =
- ProjectionCacheKey::from_poly_projection_predicate(self, data)
+ ProjectionCacheKey::from_poly_projection_obligation(
+ self,
+ &project_obligation,
+ )
{
if let Some(cached_res) = self
.infcx
@@ -844,8 +847,9 @@
&& (eval_rslt == EvaluatedToOk
|| eval_rslt == EvaluatedToOkModuloRegions)
&& let Some(key) =
- ProjectionCacheKey::from_poly_projection_predicate(
- self, data,
+ ProjectionCacheKey::from_poly_projection_obligation(
+ self,
+ &project_obligation,
)
{
// If the result is something that we can cache, then mark this