We ran into this issue with nested Any() as well, digging into the debug traces, you can see that the inner any failed the individual parsers but didn't return any error back up the chain.
=== RUN TestAny/Nested/Any(Seq,Any)
combinator_test.go:97 | bob | ps {
combinator_test.go:94 | bob | seq {
combinator_test.go:94 | | [a-z] found "bob"
combinator_test.go:94 | | : did not find :
combinator_test.go:94 | bob | } did not find :
combinator_test.go:93 | bob | anyTrueFalse {
combinator_test.go:93 | bob | true did not find true
combinator_test.go:93 | bob | false did not find false
combinator_test.go:93 | bob | } found "[bob,]"
combinator_test.go:97 | bob | } found "[bob,]"
What happens is in the outer Any() it runs a parser which sets an error, it then calls recover and calls the next parser. If that parser is an Any() then it saves error in longestError, but because recover was called, pos is set, but expected is empty. Subsequently the inner Any() will check the error pos against longest, but if all the inner Any()'s errors are before the outer one, it ends up returning out of the inner any() without having updated longestError. When it then returns back up the chain, error.expected is still not set.
This fix checks expected as well as pos when checking if it should update longestError.
We ran into this issue with nested Any() as well, digging into the debug traces, you can see that the inner any failed the individual parsers but didn't return any error back up the chain.
What happens is in the outer Any() it runs a parser which sets an error, it then calls recover and calls the next parser. If that parser is an Any() then it saves error in longestError, but because recover was called, pos is set, but expected is empty. Subsequently the inner Any() will check the error pos against longest, but if all the inner Any()'s errors are before the outer one, it ends up returning out of the inner any() without having updated longestError. When it then returns back up the chain, error.expected is still not set.
This fix checks expected as well as pos when checking if it should update longestError.