Remove concept of 'completion' from the projection cache
Fixes #88910 When we initially store a `NormalizedTy` in the projection cache, we discard all obligations that we can (while ensuring that we don't cause any issues with incremental compilation). Marking a projection cache entry as 'completed' discards all obligations associated with it. This can only cause problems, since any obligations stored in the cache are there for a reason (e.g. they evaluate to `EvaluatedToOkModuloRegions`). This commit removes `complete` and `complete_normalized` entirely.
This commit is contained in:
parent
ec9a1bdc45
commit
055651d1af
2 changed files with 2 additions and 51 deletions
|
@ -153,47 +153,6 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
|
||||||
assert!(!fresh_key, "never started projecting `{:?}`", key);
|
assert!(!fresh_key, "never started projecting `{:?}`", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark the relevant projection cache key as having its derived obligations
|
|
||||||
/// complete, so they won't have to be re-computed (this is OK to do in a
|
|
||||||
/// snapshot - if the snapshot is rolled back, the obligations will be
|
|
||||||
/// marked as incomplete again).
|
|
||||||
pub fn complete(&mut self, key: ProjectionCacheKey<'tcx>) {
|
|
||||||
let mut map = self.map();
|
|
||||||
let ty = match map.get(&key) {
|
|
||||||
Some(&ProjectionCacheEntry::NormalizedTy(ref ty)) => {
|
|
||||||
debug!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty);
|
|
||||||
ty.value
|
|
||||||
}
|
|
||||||
ref value => {
|
|
||||||
// Type inference could "strand behind" old cache entries. Leave
|
|
||||||
// them alone for now.
|
|
||||||
debug!("ProjectionCacheEntry::complete({:?}) - ignoring {:?}", key, value);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
map.insert(
|
|
||||||
key,
|
|
||||||
ProjectionCacheEntry::NormalizedTy(Normalized { value: ty, obligations: vec![] }),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A specialized version of `complete` for when the key's value is known
|
|
||||||
/// to be a NormalizedTy.
|
|
||||||
pub fn complete_normalized(&mut self, key: ProjectionCacheKey<'tcx>, ty: &NormalizedTy<'tcx>) {
|
|
||||||
// We want to insert `ty` with no obligations. If the existing value
|
|
||||||
// already has no obligations (as is common) we don't insert anything.
|
|
||||||
if !ty.obligations.is_empty() {
|
|
||||||
self.map().insert(
|
|
||||||
key,
|
|
||||||
ProjectionCacheEntry::NormalizedTy(Normalized {
|
|
||||||
value: ty.value,
|
|
||||||
obligations: vec![],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Indicates that trying to normalize `key` resulted in
|
/// Indicates that trying to normalize `key` resulted in
|
||||||
/// ambiguity. No point in trying it again then until we gain more
|
/// ambiguity. No point in trying it again then until we gain more
|
||||||
/// type information (in which case, the "fully resolved" key will
|
/// type information (in which case, the "fully resolved" key will
|
||||||
|
|
|
@ -14,18 +14,17 @@ use super::util;
|
||||||
use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
|
use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def};
|
||||||
use super::wf;
|
use super::wf;
|
||||||
use super::DerivedObligationCause;
|
use super::DerivedObligationCause;
|
||||||
|
use super::Normalized;
|
||||||
use super::Obligation;
|
use super::Obligation;
|
||||||
use super::ObligationCauseCode;
|
use super::ObligationCauseCode;
|
||||||
use super::Selection;
|
use super::Selection;
|
||||||
use super::SelectionResult;
|
use super::SelectionResult;
|
||||||
use super::TraitQueryMode;
|
use super::TraitQueryMode;
|
||||||
use super::{Normalized, ProjectionCacheKey};
|
|
||||||
use super::{ObligationCause, PredicateObligation, TraitObligation};
|
use super::{ObligationCause, PredicateObligation, TraitObligation};
|
||||||
use super::{Overflow, SelectionError, Unimplemented};
|
use super::{Overflow, SelectionError, Unimplemented};
|
||||||
|
|
||||||
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
use crate::infer::{InferCtxt, InferOk, TypeFreshener};
|
||||||
use crate::traits::error_reporting::InferCtxtExt;
|
use crate::traits::error_reporting::InferCtxtExt;
|
||||||
use crate::traits::project::ProjectionCacheKeyExt;
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
|
@ -574,14 +573,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
match project::poly_project_and_unify_type(self, &project_obligation) {
|
match project::poly_project_and_unify_type(self, &project_obligation) {
|
||||||
Ok(Ok(Some(mut subobligations))) => {
|
Ok(Ok(Some(mut subobligations))) => {
|
||||||
self.add_depth(subobligations.iter_mut(), obligation.recursion_depth);
|
self.add_depth(subobligations.iter_mut(), obligation.recursion_depth);
|
||||||
let result = self
|
self.evaluate_predicates_recursively(previous_stack, subobligations)
|
||||||
.evaluate_predicates_recursively(previous_stack, subobligations);
|
|
||||||
if let Some(key) =
|
|
||||||
ProjectionCacheKey::from_poly_projection_predicate(self, data)
|
|
||||||
{
|
|
||||||
self.infcx.inner.borrow_mut().projection_cache().complete(key);
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
Ok(Ok(None)) => Ok(EvaluatedToAmbig),
|
Ok(Ok(None)) => Ok(EvaluatedToAmbig),
|
||||||
Ok(Err(project::InProgress)) => Ok(EvaluatedToRecur),
|
Ok(Err(project::InProgress)) => Ok(EvaluatedToRecur),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue