Skip to content

Exponential time in formatting nested brackets? #106

@y1ca1

Description

@y1ca1

In some cases, we'd like to convert between Rust enums and structural binary sum types like:

enum Either<T, U> {
    Left(T),
    Right(U),
}

pub enum Enum {
    Variant0(u32),
    Variant1(u32),
    Variant2(u32),
    Variant3(u32),
    Variant4(u32),
}

pub type EnumInner = Either<u32, Either<u32, Either<u32, Either<u32, u32>>>>;

fn convert(m: Enum) -> EnumInner {
    match m {
        Enum::Variant0(m) => Either::Left(m),
        Enum::Variant1(m) => Either::Right(Either::Left(m)),
        Enum::Variant2(m) => Either::Right(Either::Right(Either::Left(m))),
        Enum::Variant3(m) => Either::Right(Either::Right(Either::Right(Either::Left(m)))),
        Enum::Variant4(m) => Either::Right(Either::Right(Either::Right(Either::Right(m)))),
    }
}

fn convert_inv(m: EnumInner) -> Enum {
    match m {
        Either::Left(m) => Enum::Variant0(m),
        Either::Right(Either::Left(m)) => Enum::Variant1(m),
        Either::Right(Either::Right(Either::Left(m))) => Enum::Variant2(m),
        Either::Right(Either::Right(Either::Right(Either::Left(m)))) => Enum::Variant3(m),
        Either::Right(Either::Right(Either::Right(Either::Right(m)))) => Enum::Variant4(m),
    }
}

verusfmt can handle this pattern up to ~27 variants on my MacBook Pro M3. It took verusfmt ~5s to format 20 variants, and the time it took to process more variants exponentially increases henceforth.

The good news (or bad news?) is that rustfmt also timed out at ~30 variants.

You can play with it using this python script: https://github.com/secure-foundations/vest/blob/main/vest-dsl/test/test_fmt_nested.py

Usage: test_fmt_nested.py <verusfmt|rustfmt> <number_of_variants>

Also related: it seems like formatting pest's autogenerated parsers (similar to what we have for Vest) is an open issue for rustfmt: rust-lang/rustfmt#5500, rust-lang/rustfmt#4867, rust-lang/rustfmt#4476

Metadata

Metadata

Assignees

No one assigned

    Labels

    performancePerformance is suboptimal or improvable

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions