Skip to content

Nested closures result in exponential compilation time increase #72408

Closed
@VFLashM

Description

@VFLashM

Closures include captured types twice in a type tree.

Wrapping one closure with another leads to doubling the amount of types in the type tree.

With nested closures compile time increases exponentially and it's extremely easy to break the compiler. Obviously it's even easier if each level captures more than one closure.

I think I have a fix for this one ready, about to push it.

I tried this code:

fn dup<F: Fn(i32) -> i32>(f: F) -> impl Fn(i32) -> i32 {
    move |a| f(2*a)
}

fn main() {
    let f = |a| a;

    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);

    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);

    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);

    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);

    // Compiler dies around here if it tries
    // to walk the tree exhaustively.

    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);

    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);
    let f = dup(f);

    println!("Hello {}", f(1));
}

I expected to see this happen: no error.

Instead, this happened:

error: reached the type-length limit while instantiating `dup::<[closure@src/main.rs:2:5: ...rs:6:13: 6:18]]]]]]]]]]]]]]]]]]>`
 --> src/main.rs:1:1
  |
1 | / fn dup<F: Fn(i32) -> i32>(f: F) -> impl Fn(i32) -> i32 {
2 | |     move |a| f(2*a)
3 | | }
  | |_^
  |
  = note: consider adding a `#![type_length_limit="1835001"]` attribute to your crate

Meta

I tried it both on stable and nightly rust:

$ rustc --version --verbose
rustc 1.45.0-nightly (7ebd87a7a 2020-05-08)
binary: rustc
commit-hash: 7ebd87a7a1e0e21767422e115c9455ef6e6d4bee
commit-date: 2020-05-08
host: x86_64-pc-windows-msvc
release: 1.45.0-nightly
LLVM version: 9.0
$ rustc --version --verbose
rustc 1.43.0 (4fb7144ed 2020-04-20)
binary: rustc
commit-hash: 4fb7144ed159f94491249e86d5bbd033b5d60550
commit-date: 2020-04-20
host: x86_64-pc-windows-msvc
release: 1.43.0
LLVM version: 9.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)C-bugCategory: This is a bug.I-compiletimeIssue: Problems and improvements with respect to compile times.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions