include ParamEnv in projection cache key
This commit is contained in:
parent
584f183dc0
commit
88b10c1162
@ -78,11 +78,12 @@ pub struct ProjectionCacheStorage<'tcx> {
|
||||
#[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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -758,9 +758,9 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
|
||||
// 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'
|
||||
|
@ -344,7 +344,7 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
||||
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 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
|
||||
}
|
||||
|
||||
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,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -815,7 +815,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// `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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&& (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
|
||||
|
Loading…
x
Reference in New Issue
Block a user