Skip to content

Commit cc30aa2

Browse files
authored
fix parser span ranges for && and || join2 errors
1 parent 1643ea7 commit cc30aa2

1 file changed

Lines changed: 26 additions & 4 deletions

File tree

cel-parser/src/lib.rs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ impl CELParser {
462462
/// Returns an error if the RHS is missing after `||`, if the RHS does not
463463
/// produce a `bool`, or if any sub-expression returns an error.
464464
fn is_or_expression(&mut self) -> Result<bool> {
465+
let start_span = self.peek_span();
465466
if self.is_and_expression()? {
466467
while self.is_punctuation("||") {
467468
let mut rhs_fragment = self.context.new_fragment();
@@ -474,7 +475,13 @@ impl CELParser {
474475
bypass_fragment.just(true);
475476
self.context
476477
.join2(bypass_fragment, rhs_fragment)
477-
.map_err(|e| ParseError::new(e.to_string(), self.last_span))?;
478+
.map_err(|e| {
479+
ParseError::new_range(
480+
e.to_string(),
481+
start_span.expect("production has token at start"),
482+
self.last_span,
483+
)
484+
})?;
478485
}
479486
Ok(true)
480487
} else {
@@ -489,6 +496,7 @@ impl CELParser {
489496
/// Returns an error if the RHS is missing after `&&`, if the RHS does not
490497
/// produce a `bool`, or if any sub-expression returns an error.
491498
fn is_and_expression(&mut self) -> Result<bool> {
499+
let start_span = self.peek_span();
492500
if self.is_comparison_expression()? {
493501
while self.is_punctuation("&&") {
494502
let mut rhs_fragment = self.context.new_fragment();
@@ -501,7 +509,13 @@ impl CELParser {
501509
bypass_fragment.just(false);
502510
self.context
503511
.join2(rhs_fragment, bypass_fragment)
504-
.map_err(|e| ParseError::new(e.to_string(), self.last_span))?;
512+
.map_err(|e| {
513+
ParseError::new_range(
514+
e.to_string(),
515+
start_span.expect("production has token at start"),
516+
self.last_span,
517+
)
518+
})?;
505519
}
506520
Ok(true)
507521
} else {
@@ -1647,14 +1661,22 @@ mod tests {
16471661
fn and_lhs_type_error() {
16481662
// LHS is i32, not bool — join2 must reject it at parse time.
16491663
let mut parser = CELParser::new(OpLookup::new());
1650-
assert!(parser.parse_str("1i32 && true").is_err());
1664+
let err = match parser.parse_str("1i32 && true") {
1665+
Err(e) => e,
1666+
Ok(_) => panic!("lhs i32 should fail for &&"),
1667+
};
1668+
assert!(err.end_span().is_some());
16511669
}
16521670

16531671
#[test]
16541672
fn or_lhs_type_error() {
16551673
// LHS is i32, not bool — join2 must reject it at parse time.
16561674
let mut parser = CELParser::new(OpLookup::new());
1657-
assert!(parser.parse_str("1i32 || true").is_err());
1675+
let err = match parser.parse_str("1i32 || true") {
1676+
Err(e) => e,
1677+
Ok(_) => panic!("lhs i32 should fail for ||"),
1678+
};
1679+
assert!(err.end_span().is_some());
16581680
}
16591681

16601682
#[test]

0 commit comments

Comments
 (0)