Skip to content

Commit a1815d7

Browse files
committed
This effectively reverts rust-lang#43546 as it seems that it does affect performance more than the PR has anticipated. Follow-up changes from rust-lang#44269 are also reverted. This also removes the deduplication code from rust-lang#48296 as duplications were primarily coming from rust-lang#43546 and after removing that code it probably doesn't worth paying the cost of using a hash map.
1 parent fc81ad2 commit a1815d7

File tree

3 files changed

+10
-57
lines changed

3 files changed

+10
-57
lines changed

compiler/rustc_infer/src/traits/project.rs

+5-24
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ pub enum ProjectionCacheEntry<'tcx> {
9292
Ambiguous,
9393
Recur,
9494
Error,
95-
NormalizedTy(NormalizedTy<'tcx>),
95+
NormalizedTy(Ty<'tcx>),
9696
}
9797

9898
impl<'tcx> ProjectionCacheStorage<'tcx> {
@@ -149,7 +149,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
149149
debug!("Not overwriting Recur");
150150
return;
151151
}
152-
let fresh_key = map.insert(key, ProjectionCacheEntry::NormalizedTy(value));
152+
let fresh_key = map.insert(key, ProjectionCacheEntry::NormalizedTy(value.value));
153153
assert!(!fresh_key, "never started projecting `{:?}`", key);
154154
}
155155

@@ -160,9 +160,9 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
160160
pub fn complete(&mut self, key: ProjectionCacheKey<'tcx>) {
161161
let mut map = self.map();
162162
let ty = match map.get(&key) {
163-
Some(&ProjectionCacheEntry::NormalizedTy(ref ty)) => {
163+
Some(&ProjectionCacheEntry::NormalizedTy(ty)) => {
164164
debug!("ProjectionCacheEntry::complete({:?}) - completing {:?}", key, ty);
165-
ty.value
165+
ty
166166
}
167167
ref value => {
168168
// Type inference could "strand behind" old cache entries. Leave
@@ -172,26 +172,7 @@ impl<'tcx> ProjectionCache<'_, 'tcx> {
172172
}
173173
};
174174

175-
map.insert(
176-
key,
177-
ProjectionCacheEntry::NormalizedTy(Normalized { value: ty, obligations: vec![] }),
178-
);
179-
}
180-
181-
/// A specialized version of `complete` for when the key's value is known
182-
/// to be a NormalizedTy.
183-
pub fn complete_normalized(&mut self, key: ProjectionCacheKey<'tcx>, ty: &NormalizedTy<'tcx>) {
184-
// We want to insert `ty` with no obligations. If the existing value
185-
// already has no obligations (as is common) we don't insert anything.
186-
if !ty.obligations.is_empty() {
187-
self.map().insert(
188-
key,
189-
ProjectionCacheEntry::NormalizedTy(Normalized {
190-
value: ty.value,
191-
obligations: vec![],
192-
}),
193-
);
194-
}
175+
map.insert(key, ProjectionCacheEntry::NormalizedTy(ty));
195176
}
196177

197178
/// Indicates that trying to normalize `key` resulted in

compiler/rustc_trait_selection/src/traits/project.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -519,18 +519,12 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
519519
Err(ProjectionCacheEntry::NormalizedTy(ty)) => {
520520
// This is the hottest path in this function.
521521
//
522-
// If we find the value in the cache, then return it along
523-
// with the obligations that went along with it. Note
524-
// that, when using a fulfillment context, these
525-
// obligations could in principle be ignored: they have
526-
// already been registered when the cache entry was
527-
// created (and hence the new ones will quickly be
528-
// discarded as duplicated). But when doing trait
529-
// evaluation this is not the case, and dropping the trait
530-
// evaluations can causes ICEs (e.g., #43132).
522+
// If we find the value in the cache, then the obligations
523+
// have already been returned from the previous entry (and
524+
// should therefore have been honored).
531525
debug!(?ty, "found normalized ty");
532-
obligations.extend(ty.obligations);
533-
return Ok(Some(ty.value));
526+
527+
return Ok(Some(ty));
534528
}
535529
Err(ProjectionCacheEntry::Error) => {
536530
debug!("opt_normalize_projection_type: found error");

compiler/rustc_trait_selection/src/traits/select/mod.rs

-22
Original file line numberDiff line numberDiff line change
@@ -2083,28 +2083,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
20832083
});
20842084
}
20852085

2086-
// We are performing deduplication here to avoid exponential blowups
2087-
// (#38528) from happening, but the real cause of the duplication is
2088-
// unknown. What we know is that the deduplication avoids exponential
2089-
// amount of predicates being propagated when processing deeply nested
2090-
// types.
2091-
//
2092-
// This code is hot enough that it's worth avoiding the allocation
2093-
// required for the FxHashSet when possible. Special-casing lengths 0,
2094-
// 1 and 2 covers roughly 75-80% of the cases.
2095-
if obligations.len() <= 1 {
2096-
// No possibility of duplicates.
2097-
} else if obligations.len() == 2 {
2098-
// Only two elements. Drop the second if they are equal.
2099-
if obligations[0] == obligations[1] {
2100-
obligations.truncate(1);
2101-
}
2102-
} else {
2103-
// Three or more elements. Use a general deduplication process.
2104-
let mut seen = FxHashSet::default();
2105-
obligations.retain(|i| seen.insert(i.clone()));
2106-
}
2107-
21082086
obligations
21092087
}
21102088
}

0 commit comments

Comments
 (0)