Skip to content
This repository was archived by the owner on Apr 2, 2026. It is now read-only.

Commit 8740951

Browse files
authored
fix: map_err loses some of what is expected in error when used sequentially (#835) (#836)
1 parent 480010a commit 8740951

2 files changed

Lines changed: 50 additions & 21 deletions

File tree

src/combinator.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2867,10 +2867,16 @@ where
28672867
let start = inp.cursor();
28682868
let old_alt = inp.take_alt();
28692869
let res = self.parser.go::<M>(inp);
2870+
let new_alt = inp.take_alt();
28702871

2871-
if res.is_err() {
2872+
if res.is_ok() {
2873+
inp.errors.alt = old_alt;
2874+
if let Some(new_alt) = new_alt {
2875+
inp.add_alt_err(&new_alt.pos, new_alt.err);
2876+
}
2877+
} else {
28722878
// Can't fail!
2873-
let mut new_alt = inp.take_alt().unwrap();
2879+
let mut new_alt = new_alt.unwrap();
28742880
let span = inp.span_since(&start);
28752881
new_alt.err = (self.mapper)(new_alt.err, span, inp.state());
28762882

src/lib.rs

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3761,30 +3761,53 @@ mod tests {
37613761
#[test]
37623762
#[allow(dead_code)]
37633763
fn map_err_missed_info() {
3764-
use crate::LabelError;
3764+
use crate::{extra::Err, LabelError};
37653765

3766-
fn zero<'src>() -> impl Parser<'src, &'src str, (), extra::Err<Rich<'src, char>>> {
3767-
just("-")
3768-
.or_not()
3769-
.then(just("0").map_err(move |e: Rich<_>| {
3770-
LabelError::<&str, char>::expected_found(
3771-
['n'],
3772-
e.found().map(|i| From::from(*i)),
3773-
*e.span(),
3774-
)
3775-
}))
3776-
.ignored()
3766+
fn erroneous_map_err<'src>() -> impl Parser<'src, &'src str, (), Err<Rich<'src, char>>> {
3767+
group((
3768+
just("a").or_not(),
3769+
just("b").map_err(|mut err| {
3770+
LabelError::<&str, _>::label_with(&mut err, 'l');
3771+
err
3772+
}),
3773+
))
3774+
.ignored()
37773775
}
37783776

37793777
assert_eq!(
3780-
zero().parse("_0").into_result(),
3781-
Err(vec![
3782-
<Rich<char> as LabelError::<&str, char>>::expected_found(
3783-
['-', 'n'],
3778+
erroneous_map_err().parse("_").into_output_errors(),
3779+
(
3780+
None,
3781+
vec![LabelError::<&str, _>::expected_found(
3782+
['a', 'l'],
37843783
Some('_'.into()),
3785-
(0..1).into(),
3786-
)
3787-
]),
3784+
SimpleSpan::new((), 0..1),
3785+
)]
3786+
),
3787+
);
3788+
3789+
fn erroneous_then<'src>() -> impl Parser<'src, &'src str, (), Err<Rich<'src, char>>> {
3790+
group((
3791+
just("a").or_not(),
3792+
empty().map_err(|mut err| {
3793+
LabelError::<&str, _>::label_with(&mut err, 'l');
3794+
err
3795+
}),
3796+
just("c"),
3797+
))
3798+
.ignored()
3799+
}
3800+
3801+
assert_eq!(
3802+
erroneous_then().parse("_").into_output_errors(),
3803+
(
3804+
None,
3805+
vec![LabelError::<&str, _>::expected_found(
3806+
['a', 'c'],
3807+
Some('_'.into()),
3808+
SimpleSpan::new((), 0..1),
3809+
)]
3810+
),
37883811
);
37893812
}
37903813

0 commit comments

Comments
 (0)