fix(parser/error): Remove multiple errors from line number calc

Errors were contextualized by finding their index in the source file.
This method is extremely flaky, as it _hopes_ that the line is not
spread over multiple lines.
The new method actually uses the span to calculate a matched line and
thus avoids any issues related to the actual position of the line in the
source file.
This commit is contained in:
Benedikt Peetz 2024-03-24 19:59:21 +01:00
parent a50936f264
commit e512352f73
Signed by: bpeetz
GPG Key ID: A5E94010C3A642AD
1 changed files with 11 additions and 5 deletions

View File

@ -74,13 +74,19 @@ impl ErrorContext {
.expect("This should work, as have *at least* one (index = 0) line")) .expect("This should work, as have *at least* one (index = 0) line"))
.to_owned(); .to_owned();
// Make the span relative to the current line
let contexted_span = { let contexted_span = {
let matched_line: Vec<_> = original_file.match_indices(&line).collect(); // `spanned_line` should be a subset of `line`
let spanned_line = &original_file[span.start..span.end];
let matched_line: Vec<_> = line.match_indices(&spanned_line).collect();
assert!(!matched_line.is_empty());
let (index, matched_line) = matched_line.first().expect("This first index should always match, as we took the line from the string in the first place"); let (index, matched_line) = matched_line.first().expect("This first index should always match, as we took the line from the string in the first place");
debug_assert_eq!(matched_line, &&line); debug_assert_eq!(matched_line, &spanned_line);
TokenSpan { TokenSpan {
start: span.start - index, start: *index,
end: span.end - index, end: (span.end - span.start) + index,
} }
}; };
@ -94,7 +100,7 @@ impl ErrorContext {
.to_owned() .to_owned()
}; };
let line_below = if lines.len() - 1 > line_number { let line_below = if lines.len() > line_number {
// We have a line after the current line // We have a line after the current line
(*lines (*lines
.get((line_number + 1) - 1) .get((line_number + 1) - 1)