Skip to content

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

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