Skip to content

Commit

Permalink
Improved error tracking for repeated and try_map
Browse files Browse the repository at this point in the history
  • Loading branch information
zesterer committed Dec 15, 2024
1 parent d08cafc commit f0a8694
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 11 deletions.
10 changes: 6 additions & 4 deletions src/combinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,8 +547,12 @@ where
let before = inp.cursor();
let out = self.parser.go::<Emit>(inp)?;
let span = inp.span_since(&before);
let old_alt = inp.errors.alt.take();
match (self.mapper)(out, span) {
Ok(out) => Ok(M::bind(|| out)),
Ok(out) => {
inp.errors.alt = old_alt;
Ok(M::bind(|| out))
}
Err(err) => {
inp.add_alt_err(&before.inner, err);
Err(())
Expand Down Expand Up @@ -1444,8 +1448,6 @@ where
match self.parser.go::<Check>(inp) {
Ok(()) => {}
Err(()) => {
// TODO: Helper for this? Rewind does this? (seconds one may be bad for other cases)
inp.errors.alt = None;
inp.rewind(before);
break Ok(M::bind(|| ()));
}
Expand Down Expand Up @@ -2715,7 +2717,7 @@ where
let mut emitter = Emitter::new();
let out = (self.validator)(out, &mut MapExtra::new(&before, inp), &mut emitter);
for err in emitter.errors() {
inp.emit(err);
inp.emit(before.clone(), err);
}
Ok(M::bind(|| out))
}
Expand Down
14 changes: 10 additions & 4 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1702,10 +1702,16 @@ impl<'src, 'parse, I: Input<'src>, E: ParserExtra<'src, I>> InputRef<'src, 'pars
}

#[inline]
pub(crate) fn emit(&mut self, error: E::Error) {
self.errors
.secondary
.push(Located::at(self.cursor.clone(), error));
pub(crate) fn emit(
&mut self,
cursor: impl Into<Option<Cursor<'src, 'parse, I>>>,
error: E::Error,
) {
let cursor = cursor
.into()
.map(|c| c.inner)
.unwrap_or_else(|| self.cursor.clone());
self.errors.secondary.push(Located::at(cursor, error));
}

#[inline]
Expand Down
28 changes: 28 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3569,4 +3569,32 @@ mod tests {
<Rich<_, _, _> as LabelError<&str, _>>::label_with(&mut err, "greeting");
assert_eq!(parser2().parse("goodbye").into_errors(), vec![err]);
}

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

fn string<'src>() -> impl Parser<'src, &'src str, &'src str, extra::Err<Rich<'src, char>>> {
let quote = just("\"");
let escaped = just("\\").then(just("n"));
let unescaped = none_of("\\\"");

unescaped
.ignored()
.or(escaped.ignored())
.repeated()
.to_slice()
.delimited_by(quote, quote)
}

assert_eq!(
string().parse(r#""Hello\m""#).into_result(),
Err(vec![<Rich<char> as Error::<&str>>::expected_found(
Some(Some('n'.into())),
Some('m'.into()),
(7..8).into(),
)]),
);
}
}
6 changes: 3 additions & 3 deletions src/recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ where
return Err(());
}
};
inp.emit(alt.err);
inp.emit(None, alt.err);
Ok(out)
}
}
Expand Down Expand Up @@ -132,7 +132,7 @@ where
.secondary_errors_since(before.err_count)
.is_empty()
}) {
inp.emit(alt.err);
inp.emit(None, alt.err);
break Ok(out);
} else {
inp.errors.alt.take();
Expand Down Expand Up @@ -174,7 +174,7 @@ where
loop {
let before = inp.save();
if let Ok(()) = self.until.go::<Check>(inp) {
inp.emit(alt.err);
inp.emit(None, alt.err);
break Ok(M::bind(|| (self.fallback)()));
}
inp.rewind(before);
Expand Down

0 comments on commit f0a8694

Please sign in to comment.