I finished following along in this tutorial about writing your own parser combinators, and partway through, there was a bug in the implementation that the author anticipated, and demonstrated a fix for:
error: reached the type-length limit while instantiating `pair::<for<'r> fn(&'r str) -> st...::St ring, std::string::String)>>`
I am having trouble understanding more about how this happens. The solution is to implement a way to shove portions of the parsers you build up into
Boxes, but I am still unclear how the types explode in the first place.
I sort of understand the example regarding how a
Box is needed for implementing the type for a linked list, but I don’t see how this parser combinator implementation causes the types to balloon out of control.
I have attempted to get the compiler to print out the types of things by giving it faulty annotations, like this:
let z: i32 = zero_or_more(right(space1(), attribute_pair()))
But the error message does not appear to expose a particularly daunting type:
error[E0308]: mismatched types --> src/lib.rs:363:18 | 363 | let z: i32 = zero_or_more(right(space1(), attribute_pair())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected i32, found opaque type | = note: expected type `i32` found type `impl Parser<'_, std::vec::Vec<(std::string::String, std::string::String)>>`
What can I read to learn more about this problem, and how do I get feedback in the code I’ve written to detect these kinds of type explosions earlier? How do I inspect what I’ve written to see the kind of
type_length burden my code is incurring?