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