diff options
| author | bors <bors@rust-lang.org> | 2021-09-27 14:08:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-09-27 14:08:13 +0000 |
| commit | 2b6ed3b675475abc01ce7e68bb75b457f0c85684 (patch) | |
| tree | e17c038639d97f818bf2d3d19696d929320aa1e8 | |
| parent | 3e8f32e1c52ca493c862facb7a69e7c3f1f97a18 (diff) | |
| parent | a84e3fab307f562312c54991e3c7386246ba3f75 (diff) | |
| download | rust-2b6ed3b675475abc01ce7e68bb75b457f0c85684.tar.gz rust-2b6ed3b675475abc01ce7e68bb75b457f0c85684.zip | |
Auto merge of #89285 - jackh726:issue-88862, r=nikomatsakis
Don't normalize opaque types with escaping late-bound regions Fixes #88862 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. Needs a perf run once https://github.com/rust-lang/rustc-perf/pull/1033 is merged r? `@nikomatsakis`
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/project.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/query/normalize.rs | 8 |
2 files changed, 8 insertions, 8 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index baf6b725648..47b006985ec 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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( diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index ed5fe466c69..1364cf1c995 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -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) { |
