From b7faec7e0a69394c5d0689c55cdb393f9ae44147 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 05:18:25 +0000 Subject: [PATCH 1/2] Fix error location caret positioning in eldritch-core The `format_error` function in `eldritch-core` previously used a static indentation for the `^-- here` marker, which caused it to misalign when the code line was trimmed or when the error was not at the start of the trimmed content. This change calculates the dynamic column offset relative to the trimmed line content and adds appropriate padding to align the caret correctly. --- .../eldritch-core/src/interpreter/core.rs | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/implants/lib/eldritchv2/eldritch-core/src/interpreter/core.rs b/implants/lib/eldritchv2/eldritch-core/src/interpreter/core.rs index 23d8237bd..46cfca9d7 100644 --- a/implants/lib/eldritchv2/eldritch-core/src/interpreter/core.rs +++ b/implants/lib/eldritchv2/eldritch-core/src/interpreter/core.rs @@ -224,10 +224,36 @@ impl Interpreter { if error.span.line > 0 && error.span.line <= lines.len() { let line_idx = error.span.line - 1; let line_content = lines[line_idx]; + + // Calculate column offset relative to trimmed line + let leading_whitespace = line_content.len() - line_content.trim_start().len(); + + // Calculate line start byte offset + let mut line_start = error.span.start; + let source_bytes = source.as_bytes(); + // Walk backwards from error start to find newline + // If error.span.start is beyond source len (shouldn't happen for valid error), clamp it. + if line_start > source_bytes.len() { + line_start = source_bytes.len(); + } + while line_start > 0 && source_bytes[line_start - 1] != b'\n' { + line_start -= 1; + } + + // Calculate raw column (byte offset from start of line) + let raw_col = error.span.start.saturating_sub(line_start); + + // Calculate display column relative to trimmed string + let display_col = raw_col.saturating_sub(leading_whitespace); + + // Create dynamic padding + let padding = format!("{:>width$}", "", width = display_col); + output.push_str(&format!( - "\n\nError location:\n at line {}:\n {}\n ^-- here", + "\n\nError location:\n at line {}:\n {}\n {}^-- here", error.span.line, - line_content.trim() + line_content.trim(), + padding )); } output From 09c60576394c0ed7a8590f003abf6a366f205369 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 12 Dec 2025 05:34:24 +0000 Subject: [PATCH 2/2] Fix error location caret positioning in eldritch-core and add test The `format_error` function in `eldritch-core` previously used a static indentation for the `^-- here` marker, which caused it to misalign when the code line was trimmed or when the error was not at the start of the trimmed content. This change calculates the dynamic column offset relative to the trimmed line content and adds appropriate padding to align the caret correctly. Added `tests/error_alignment.rs` to verify correct caret positioning with and without indentation. --- .../eldritch-core/tests/error_alignment.rs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 implants/lib/eldritchv2/eldritch-core/tests/error_alignment.rs diff --git a/implants/lib/eldritchv2/eldritch-core/tests/error_alignment.rs b/implants/lib/eldritchv2/eldritch-core/tests/error_alignment.rs new file mode 100644 index 000000000..4baf05dc8 --- /dev/null +++ b/implants/lib/eldritchv2/eldritch-core/tests/error_alignment.rs @@ -0,0 +1,50 @@ +use eldritch_core::Interpreter; + +#[test] +fn test_error_caret_alignment() { + let mut interp = Interpreter::new(); + + // Test case 1: Error not at start, with indentation + // " x = z + 1" + // ^ ^ + // 0 4 (relative to trimmed) + // In raw string: 4 spaces + 'x' + ' ' + '=' + ' ' + 'z' + // 'z' is at index 8. + // Trimmed line: "x = z + 1" (starts at index 4) + // Error at 8. Relative to trimmed start: 8 - 4 = 4. + // Display indent: 4 (base) + 4 (relative) = 8 spaces. + + let code = " x = z + 1"; + let res = interp.interpret(code); + match res { + Ok(_) => panic!("Expected error for 'x = z + 1'"), + Err(msg) => { + let lines: Vec<&str> = msg.lines().collect(); + // Expected output: + // ... + // Error location: + // at line 1: + // x = z + 1 + // ^-- here + + let last_line = lines.last().expect("Error message empty"); + // " ^-- here" + // 8 spaces + ^ + assert!(last_line.starts_with(" ^-- here"), "Incorrect alignment: '{}'", last_line); + } + } + + // Test case 2: Error at start of trimmed line + // Just accessing undefined 'z' + let code2 = " z"; + let res2 = interp.interpret(code2); + match res2 { + Ok(_) => panic!("Expected error for 'z'"), + Err(msg) => { + let lines: Vec<&str> = msg.lines().collect(); + let last_line = lines.last().expect("Error message empty"); + // " ^-- here" (4 spaces indent) + assert!(last_line.starts_with(" ^-- here"), "Incorrect alignment for start of line: '{}'", last_line); + } + } +}