- Notifications
You must be signed in to change notification settings - Fork 13.8k
Description
Code
I tried this code:
fn bar() -> impl Fn() { wrap(wrap(wrap(wrap(foo())))) } fn foo() -> impl Fn() { wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo()))))))) } fn wrap(f: impl Fn()) -> impl Fn() { move || f() }
I expected running cargo check
to produce an error like:
error[E0720]: cannot resolve opaque type --> src/lib.rs:5:13 | 5 | fn foo() -> impl Fn() { | ^^^^^^^^^ recursive opaque type 6 | ((wrap(wrap(wrap(wrap(wrap(foo()))))))) | --------------------------------------- returning here with type `impl Fn<()>` ... 9 | fn wrap(f: impl Fn()) -> impl Fn() { | --------- returning this opaque type `impl Fn<()>`
It does, but cargo check
takes time exponential in the number of wrap
calls, although doesn't appear to use any extra memory.
In foo
the time take looks like:
Num wraps s | Time taken (s) |
---|---|
4 | 0.5 |
5 | 2.1 |
6 | 28 |
7 | 436 |
I believe it's also exponential in the number of wrap
calls in bar
.
The reason I had code like this was because I was using nom's parser combinators which results in lots of nested closures. I spotted it because this caused rust-analyzer to hang because cargo clippy hung (it looks like check was the issue), I had to kill clippy to fix it.
Bisection results
I bisected this (with cargo-bisect-rustc) to find the regression in nightly-2019-10-16
, which contained the following bors commits:
- Auto merge of Rollup of 4 pull requests #65433 - Centril:rollup-rzvry15, r=Centril
- Auto merge of Rollup of 14 pull requests #65454 - tmandry:rollup-0k6jiik, r=tmandry
- Auto merge of Update clippy #65450 - Manishearth:clippyup, r=Manishearth
- Auto merge of use precalculated dominators in explain_borrow #65172 - tanriol:explain_borrow-use-context-dominators, r=nagisa
- Auto merge of Update cargo, books #65445 - ehuss:update-cargo-books, r=alexcrichton
@rustbot modify labels: +regression-from-stable-to-stable -regression-untriaged