Skip to content

Commit a606ffd

Browse files
committed
Avoid exponential behaviour when relating types
1 parent 13db650 commit a606ffd

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

src/librustc/infer/equate.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,13 @@ impl TypeRelation<'tcx> for Equate<'combine, 'infcx, 'tcx> {
125125
where
126126
T: Relate<'tcx>,
127127
{
128-
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
129-
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
128+
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
129+
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
130+
self.fields.higher_ranked_sub(b, a, self.a_is_expected)
131+
} else {
132+
// Fast path for the common case.
133+
self.relate(a.skip_binder(), b.skip_binder())?;
134+
return Ok(a.clone());
135+
}
130136
}
131137
}

src/librustc/infer/nll_relate/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,10 @@ where
529529
b = self.infcx.shallow_resolve(b);
530530
}
531531

532+
if a == b {
533+
return Ok(a);
534+
}
535+
532536
match (&a.kind, &b.kind) {
533537
(_, &ty::Infer(ty::TyVar(vid))) => {
534538
if D::forbid_inference_vars() {
@@ -638,6 +642,13 @@ where
638642

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

645+
if !a.skip_binder().has_escaping_bound_vars() && !b.skip_binder().has_escaping_bound_vars()
646+
{
647+
// Fast path for the common case.
648+
self.relate(a.skip_binder(), b.skip_binder())?;
649+
return Ok(a.clone());
650+
}
651+
641652
if self.ambient_covariance() {
642653
// Covariance, so we want `for<..> A <: for<..> B` --
643654
// therefore we compare any instantiation of A (i.e., A
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Check that this can be compiled in a reasonable time.
2+
3+
// build-pass
4+
5+
fn main() {
6+
// 96 nested closures
7+
let x = ();
8+
|| || || || || || || ||
9+
|| || || || || || || ||
10+
|| || || || || || || ||
11+
|| || || || || || || ||
12+
13+
|| || || || || || || ||
14+
|| || || || || || || ||
15+
|| || || || || || || ||
16+
|| || || || || || || ||
17+
18+
|| || || || || || || ||
19+
|| || || || || || || ||
20+
|| || || || || || || ||
21+
|| || || || || || || ||
22+
[&(), &x];
23+
}

0 commit comments

Comments
 (0)