Skip to content

nom::branch::alt handles at most 21 parsers #1144

Closed
@luca-i

Description

@luca-i

Hi, I'm not sure this is a bug, maybe it is a current limitation not documented.
I think nom::branch::alt can currently handle only 21 parsers.

rustc 1.42.0 (b8cedc004 2020-03-09)
nom = "5.1.1"

use nom::branch::alt;
use nom::bytes::complete::tag;
use nom::IResult;

fn match_alternatives(input: &str) -> IResult<&str, &str> {
    alt((
        tag("alternative_01"),
        tag("alternative_02"),
        tag("alternative_03"),
        tag("alternative_04"),
        tag("alternative_05"),
        tag("alternative_06"),
        tag("alternative_07"),
        tag("alternative_08"),
        tag("alternative_09"),
        tag("alternative_10"),
        tag("alternative_11"),
        tag("alternative_12"),
        tag("alternative_13"),
        tag("alternative_14"),
        tag("alternative_15"),
        tag("alternative_16"),
        tag("alternative_17"),
        tag("alternative_18"),
        tag("alternative_19"),
        tag("alternative_20"),
        tag("alternative_21"),
        // tag("alternative_22"), // uncomment to get compiler error
    ))(input)
}

fn main() {}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_alternatives() {
        assert_eq!(
            match_alternatives("alternative_21"),
            IResult::Ok(("", "alternative_21"))
        );

        // to match "alternative_22" you must uncomment the
        // appropriate tag inside match_alternative, but at that moment
        // the code won't compile any more
        assert_eq!(
            match_alternatives("alternative_22"),
            IResult::Ok(("", "alternative_22"))
        );
    }
}

In order to get the compiler error you have to uncomment the following line inside match_alternatives function:

// tag("alternative_22"), // uncomment to get compiler error

The error message to me is a bit unclear:

^ the trait nom::branch::Alt<_, _, _> is not implemented for (impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>, impl std::ops::Fn<(_,)>)

Is there a way to overcome this limitation?
Thank you, Luca-

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