Skip to content

Commit

Permalink
Don't normalize opaque types with escaping late-bound regions.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jackh726 committed Sep 26, 2021
1 parent 497ee32 commit a84e3fa
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 8 deletions.
8 changes: 4 additions & 4 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_trait_selection/src/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit a84e3fa

Please sign in to comment.