Skip to content

Commit

Permalink
Fixed loss of error state when mapping errors
Browse files Browse the repository at this point in the history
  • Loading branch information
zesterer committed Dec 17, 2024
1 parent f0a8694 commit 773aef0
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
9 changes: 6 additions & 3 deletions src/combinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2596,12 +2596,15 @@ where
where
Self: Sized,
{
let old_alt = inp.take_alt();
let res = self.parser.go::<M>(inp);

if res.is_err() {
let mut e = inp.take_alt();
e.err = (self.mapper)(e.err);
inp.errors.alt = Some(e);
let mut new_alt = inp.take_alt();
new_alt.err = (self.mapper)(new_alt.err);

inp.errors.alt = Some(old_alt);
inp.add_alt_err(&new_alt.pos, new_alt.err);
}

res
Expand Down
9 changes: 8 additions & 1 deletion src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1729,7 +1729,14 @@ impl<'src, 'parse, I: Input<'src>, E: ParserExtra<'src, I>> InputRef<'src, 'pars

// Prioritize errors before choosing whether to generate the alt (avoids unnecessary error creation)
self.errors.alt = Some(match self.errors.alt.take() {
Some(alt) => match I::cursor_location(&alt.pos).cmp(&I::cursor_location(at)) {
Some(alt) => match {
println!(
"Add alt alt = {}, at = {}",
I::cursor_location(&alt.pos),
I::cursor_location(at)
);
I::cursor_location(&alt.pos).cmp(&I::cursor_location(at))
} {
Ordering::Equal => {
Located::at(alt.pos, alt.err.merge_expected_found(expected, found, span))
}
Expand Down
28 changes: 28 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3597,4 +3597,32 @@ mod tests {
)]),
);
}

#[test]
#[allow(dead_code)]
fn map_err_missed_info() {
use crate::error::Error;

fn zero<'src>() -> impl Parser<'src, &'src str, (), extra::Err<Rich<'src, char>>> {
just("-")
.or_not()
.then(just("0").map_err(move |e: Rich<_>| {
Error::<&str>::expected_found(
vec![Some('n'.into())],
e.found().map(|i| From::from(*i)),
e.span().clone(),
)
}))
.ignored()
}

assert_eq!(
zero().parse("_0").into_result(),
Err(vec![<Rich<char> as Error::<&str>>::expected_found(
vec![Some('-'.into()), Some('n'.into())],
Some('_'.into()),
(0..1).into(),
)]),
);
}
}

0 comments on commit 773aef0

Please sign in to comment.