Fixed reporting choice missed case.
@@ -357,20 +357,22 @@ fn validate_choices<'a, 'i: 'a>(rules: &'a Vec<ParserRule<'i>>) -> Vec<Error<'i,
.clone()
.filter_map_top_down(|node| match node.expr {
ParserExpr::Choice(ref lhs, _) => {
- match lhs.expr {
- ParserExpr::Choice(..) => None,
- _ => if is_non_failing(&lhs.expr, &map, &mut vec![]) {
+ let node = match lhs.expr {
+ ParserExpr::Choice(_, ref rhs) => rhs,
+ _ => lhs
+ };
+
+ if is_non_failing(&node.expr, &map, &mut vec![]) {
Some(Error::CustomErrorSpan {
message:
"expression cannot fail; following choices cannot be reached"
.to_owned(),
- span: lhs.span.clone()
+ span: node.span.clone()
})
} else {
None
}
}
- }
_ => None
});
@@ -774,6 +776,22 @@ mod tests {
#[test]
#[should_panic(expected = "grammar error
+ --> 1:13
+ |
+1 | a = { \"a\" | \"a\"* | \"b\" }
+ | ^--^
+ |
+ = expression cannot fail; following choices cannot be reached")]
+ fn lhs_non_failing_choice_middle() {
+ let input = "a = { \"a\" | \"a\"* | \"b\" }";
+ unwrap_or_report(consume_rules(
+ PestParser::parse(Rule::grammar_rules, input).unwrap()
+ ));
+ }
+
+ #[test]
+ #[should_panic(expected = "grammar error
+
--> 1:7
|
1 | a = { b | \"a\" } b = { \"b\"* | \"c\" }
