Use EvaluatedToOkModuloRegions
whenever we erase regions
Fixes #80691 When we evaluate a trait predicate, we convert an `EvaluatedToOk` result to `EvaluatedToOkModuloRegions` if we erased any regions. We cache the result under a region-erased 'freshened' predicate, so `EvaluatedToOk` may not be correct for other predicates that have the same cache key.
This commit is contained in:
parent
f5fe425c92
commit
102b5789b2
2 changed files with 198 additions and 1 deletions
|
@ -863,7 +863,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
stack: &TraitObligationStack<'o, 'tcx>,
|
||||
candidate: &SelectionCandidate<'tcx>,
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
let result = self.evaluation_probe(|this| {
|
||||
let mut result = self.evaluation_probe(|this| {
|
||||
let candidate = (*candidate).clone();
|
||||
match this.confirm_candidate(stack.obligation, candidate) {
|
||||
Ok(selection) => {
|
||||
|
@ -876,6 +876,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
Err(..) => Ok(EvaluatedToErr),
|
||||
}
|
||||
})?;
|
||||
|
||||
// If we erased any lifetimes, then we want to use
|
||||
// `EvaluatedToOkModuloRegions` instead of `EvaluatedToOk`
|
||||
// as your final result. The result will be cached using
|
||||
// the freshened trait predicate as a key, so we need
|
||||
// our result to be correct by *any* choice of original lifetimes,
|
||||
// not just the lifetime choice for this particular (non-erased)
|
||||
// predicate.
|
||||
// See issue #80691
|
||||
if stack.fresh_trait_ref.has_erased_regions() {
|
||||
result = result.max(EvaluatedToOkModuloRegions);
|
||||
}
|
||||
|
||||
debug!(?result);
|
||||
Ok(result)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue