From f14ef1cec265afd60c0c7c0320d68148cf8d34a0 Mon Sep 17 00:00:00 2001 From: Soispha Date: Sun, 24 Mar 2024 19:59:21 +0100 Subject: [PATCH] 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. --- trixy-parser/src/error.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/trixy-parser/src/error.rs b/trixy-parser/src/error.rs index b865754..e75cb0b 100644 --- a/trixy-parser/src/error.rs +++ b/trixy-parser/src/error.rs @@ -74,13 +74,19 @@ impl ErrorContext { .expect("This should work, as have *at least* one (index = 0) line")) .to_owned(); + // Make the span relative to the current line 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"); - debug_assert_eq!(matched_line, &&line); + debug_assert_eq!(matched_line, &spanned_line); + TokenSpan { - start: span.start - index, - end: span.end - index, + start: *index, + end: (span.end - span.start) + index, } }; @@ -94,7 +100,7 @@ impl ErrorContext { .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 (*lines .get((line_number + 1) - 1)