Skip to content

Commit

Permalink
Avoid exponential behaviour when relating types
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewjasper committed Feb 2, 2020
1 parent 13db650 commit a606ffd
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/librustc/infer/equate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,13 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
where
T: Relate<'tcx>,
{
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
} else {
// Fast path for the common case.
self.relate(a.skip_binder(), b.skip_binder())?;
return Ok(a.clone());
}
}
}
11 changes: 11 additions & 0 deletions src/librustc/infer/nll_relate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,10 @@ where
b = self.infcx.shallow_resolve(b);
}

if a == b {
return Ok(a);
}

match (&a.kind, &b.kind) {
(_, &ty::Infer(ty::TyVar(vid))) => {
if D::forbid_inference_vars() {
Expand Down Expand Up @@ -638,6 +642,13 @@ where

debug!("binders({:?}: {:?}, ambient_variance={:?})", a, b, self.ambient_variance);

if !a.skip_binder().has_escaping_bound_vars() && !b.skip_binder().has_escaping_bound_vars()
{
// Fast path for the common case.
self.relate(a.skip_binder(), b.skip_binder())?;
return Ok(a.clone());
}

if self.ambient_covariance() {
// Covariance, so we want `for<..> A <: for<..> B` --
// therefore we compare any instantiation of A (i.e., A
Expand Down
23 changes: 23 additions & 0 deletions src/test/ui/closures/deeply-nested_closures.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Check that this can be compiled in a reasonable time.

// build-pass

fn main() {
// 96 nested closures
let x = ();
|| || || || || || || ||
|| || || || || || || ||
|| || || || || || || ||
|| || || || || || || ||

|| || || || || || || ||
|| || || || || || || ||
|| || || || || || || ||
|| || || || || || || ||

|| || || || || || || ||
|| || || || || || || ||
|| || || || || || || ||
|| || || || || || || ||
[&(), &x];
}

0 comments on commit a606ffd

Please sign in to comment.