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

Commit f8a3a58

Browse files
committed
fix: try_map loses some of what is expected in error when used sequentially
1 parent 79b2ab3 commit f8a3a58

3 files changed

Lines changed: 53 additions & 11 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# IDE projects
22
.idea/
3+
.vscode/
34

45
# Project output
56
/target

src/combinator.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -630,25 +630,38 @@ where
630630
// Remove the pre-inner alt, to be reinserted later so we always preserve it
631631
let old_alt = inp.errors.alt.take();
632632

633-
let out = self.parser.go::<Emit>(inp)?;
633+
let res = self.parser.go::<Emit>(inp);
634634
let span = inp.span_since(&before);
635635
let new_alt = inp.errors.alt.take();
636636

637-
match (self.mapper)(out, span) {
637+
match res {
638638
Ok(out) => {
639-
// If successful, reinsert the original alt and then apply the new alt on top of it, since both are valid
640-
inp.errors.alt = old_alt;
641-
if let Some(new_alt) = new_alt {
642-
inp.add_alt_err(&before.inner, new_alt.err);
639+
match (self.mapper)(out, span) {
640+
Ok(out) => {
641+
// If successful, reinsert the original alt and then apply the new alt on top of it, since both are valid
642+
inp.errors.alt = old_alt;
643+
if let Some(new_alt) = new_alt {
644+
inp.add_alt_err(&new_alt.pos, new_alt.err);
645+
}
646+
Ok(M::bind(|| out))
647+
}
648+
649+
Err(err) => {
650+
// If unsuccessful, reinsert the original alt but replace the new alt with the mapper error (since it overrides it)
651+
inp.errors.alt = old_alt;
652+
inp.add_alt_err(&before.inner, err);
653+
Err(())
654+
}
643655
}
644-
Ok(M::bind(|| out))
645656
}
646-
Err(err) => {
647-
// If unsuccessful, reinsert the original alt but replace the new alt with the mapper error (since it overrides it)
657+
658+
Err(_) => {
648659
inp.errors.alt = old_alt;
649-
inp.add_alt_err(&before.inner, err);
660+
if let Some(new_alt) = new_alt {
661+
inp.add_alt_err(&new_alt.pos, new_alt.err);
662+
}
650663
Err(())
651-
}
664+
},
652665
}
653666
}
654667

src/lib.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3812,6 +3812,34 @@ mod tests {
38123812
);
38133813
}
38143814

3815+
#[test]
3816+
fn try_map() {
3817+
use crate::{DefaultExpected, LabelError};
3818+
3819+
let parser = group((
3820+
just("a").or_not(),
3821+
just("b").try_map(|_, _| Ok(())).or_not(),
3822+
just::<_, &str, extra::Err<Rich<_>>>("c"),
3823+
))
3824+
.ignored();
3825+
3826+
assert_eq!(
3827+
parser.parse("").into_output_errors(),
3828+
(
3829+
None,
3830+
vec![LabelError::<&str, _>::expected_found(
3831+
vec![
3832+
DefaultExpected::Token('a'.into()),
3833+
DefaultExpected::Token('b'.into()),
3834+
DefaultExpected::Token('c'.into()),
3835+
],
3836+
None,
3837+
SimpleSpan::new((), 0..0)
3838+
)]
3839+
)
3840+
);
3841+
}
3842+
38153843
#[test]
38163844
fn zero_size_custom_failure() {
38173845
fn my_custom<'src>() -> impl Parser<'src, &'src str, ()> {

0 commit comments

Comments
 (0)