Skip to content

Compilation time explodes exponentially when chaining .or() calls #1861

@balsoft

Description

@balsoft

I have an enum like this:

pub enum ValueType {
    Binary,
    Boolean,
    CalAddress,
    Date,
    DateTime,
    Duration,
    Float,
    Integer,
    Period,
    Recur,
    Text,
    Time,
    Uri,
    UtcOffset,
}

And I'm trying to parse its string representation with nom (actually, I'm trying to write a proc-macro to automatically parse similar enums in a similar way). This is the most obvious solution to me:

fn parse(s: &str) -> IResult<&str, ValueType> {
        tag("BINARY").map(|_| ValueType::Binary)
        .or(tag("BOOLEAN").map(|_| ValueType::Boolean))
        .or(tag("CALADDRESS").map(|_| ValueType::CalAddress))
        .or(tag("DATE").map(|_| ValueType::Date))
        .or(tag("DATETIME").map(|_| ValueType::DateTime))
        .or(tag("DURATION").map(|_| ValueType::Duration))
        .or(tag("FLOAT").map(|_| ValueType::Float))
        .or(tag("INTEGER").map(|_| ValueType::Integer))
        .or(tag("PERIOD").map(|_| ValueType::Period))
        .or(tag("RECUR").map(|_| ValueType::Recur))
        .or(tag("TEXT").map(|_| ValueType::Text))
        .or(tag("TIME").map(|_| ValueType::Time))
        .or(tag("URI").map(|_| ValueType::Uri))
        .or(tag("UTCOFFSET").map(|_| ValueType::UtcOffset))
        .parse(s)
}

This just hangs the compiler, seemingly indefinitely. Reducing the number of variants to 8 makes it compile (but very slowly), and 7 and down compiles fine. It appears to me that something somewhere is exploding the compilation time exponentially.

I understand I am probably using Nom wrong, and would be happy to know the "proper" Nom way of writing this parser; However, I also suggest mentioning somewhere in documentation that chaining parsers with or (and, I suspect, other combinators too) like this is unsupported and will blow up the compilation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions