Skip to content

Commit e31b731

Browse files
committed
Outline cold body of opt_normalize_projection_term
1 parent 54ef705 commit e31b731

1 file changed

Lines changed: 45 additions & 15 deletions

File tree

  • compiler/rustc_trait_selection/src/traits

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,49 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
315315
// bounds. It might be the case that we want two distinct caches,
316316
// or else another kind of cache entry.
317317
let cache_entry = infcx.inner.borrow_mut().projection_cache().try_start(cache_key);
318+
match cache_entry {
319+
// This is the hottest path in this function.
320+
//
321+
// If we find the value in the cache, then return it along with the
322+
// obligations that went along with it. Note that, when using a
323+
// fulfillment context, these obligations could in principle be
324+
// ignored: they have already been registered when the cache entry
325+
// was created (and hence the new ones will quickly be discarded as
326+
// duplicated). But when doing trait evaluation this is not the
327+
// case, and dropping the trait evaluations can causes ICEs (e.g.,
328+
// #43132).
329+
Err(ProjectionCacheEntry::NormalizedTerm { ty, complete: _ }) => {
330+
debug!(?ty, "found normalized ty");
331+
obligations.extend(ty.obligations);
332+
Ok(Some(ty.value))
333+
}
334+
cache_entry => opt_normalize_projection_term_slow(
335+
selcx,
336+
param_env,
337+
projection_term,
338+
cause,
339+
depth,
340+
obligations,
341+
cache_entry,
342+
cache_key,
343+
),
344+
}
345+
}
346+
347+
/// Cold-path body of [`opt_normalize_projection_term`].
348+
#[cold]
349+
#[inline(never)]
350+
fn opt_normalize_projection_term_slow<'a, 'b, 'tcx>(
351+
selcx: &'a mut SelectionContext<'b, 'tcx>,
352+
param_env: ty::ParamEnv<'tcx>,
353+
projection_term: ty::AliasTerm<'tcx>,
354+
cause: ObligationCause<'tcx>,
355+
depth: usize,
356+
obligations: &mut PredicateObligations<'tcx>,
357+
cache_entry: Result<(), ProjectionCacheEntry<'tcx>>,
358+
cache_key: ProjectionCacheKey<'tcx>,
359+
) -> Result<Option<Term<'tcx>>, InProgress> {
360+
let infcx = selcx.infcx;
318361
match cache_entry {
319362
Ok(()) => debug!("no cache"),
320363
Err(ProjectionCacheEntry::Ambiguous) => {
@@ -345,21 +388,8 @@ pub(super) fn opt_normalize_projection_term<'a, 'b, 'tcx>(
345388
debug!("recur cache");
346389
return Err(InProgress);
347390
}
348-
Err(ProjectionCacheEntry::NormalizedTerm { ty, complete: _ }) => {
349-
// This is the hottest path in this function.
350-
//
351-
// If we find the value in the cache, then return it along
352-
// with the obligations that went along with it. Note
353-
// that, when using a fulfillment context, these
354-
// obligations could in principle be ignored: they have
355-
// already been registered when the cache entry was
356-
// created (and hence the new ones will quickly be
357-
// discarded as duplicated). But when doing trait
358-
// evaluation this is not the case, and dropping the trait
359-
// evaluations can causes ICEs (e.g., #43132).
360-
debug!(?ty, "found normalized ty");
361-
obligations.extend(ty.obligations);
362-
return Ok(Some(ty.value));
391+
Err(ProjectionCacheEntry::NormalizedTerm { .. }) => {
392+
unreachable!("NormalizedTerm cache hit should be handled by the hot dispatcher");
363393
}
364394
Err(ProjectionCacheEntry::Error) => {
365395
debug!("opt_normalize_projection_type: found error");

0 commit comments

Comments
 (0)