Don't normalize opaque types with escaping late-bound regions.

Turns out, this has some really bad perf implications in large types (issue #88862). While we technically can handle them fine, it doesn't change test output either way. For now, revert with an added benchmark. Future attempts to change this back will have to consider perf.
This commit is contained in:
jackh726 2021-09-26 15:58:24 -04:00
parent 497ee321af
commit a84e3fab30
2 changed files with 8 additions and 8 deletions

View File

@ -388,15 +388,15 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
// to make sure we don't forget to fold the substs regardless.
match *ty.kind() {
ty::Opaque(def_id, substs) => {
// This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark.
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
// Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.super_fold_with(self),
Reveal::All => {
// N.b. there is an assumption here all this code can handle
// escaping bound vars.
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.depth) {
let obligation = Obligation::with_depth(

View File

@ -206,15 +206,15 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
// Wrap this in a closure so we don't accidentally return from the outer function
let res = (|| match *ty.kind() {
ty::Opaque(def_id, substs) => {
// This is really important. While we *can* handle this, this has
// severe performance implications for large opaque types with
// late-bound regions. See `issue-88862` benchmark.
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
// Only normalize `impl Trait` after type-checking, usually in codegen.
match self.param_env.reveal() {
Reveal::UserFacing => ty.super_fold_with(self),
Reveal::All => {
// N.b. there is an assumption here all this code can handle
// escaping bound vars.
let substs = substs.super_fold_with(self);
let recursion_limit = self.tcx().recursion_limit();
if !recursion_limit.value_within_limit(self.anon_depth) {