Skip to content

Commit d84a96a

Browse files
Restore full paths in spans
1 parent 8c1c70b commit d84a96a

3 files changed

Lines changed: 36 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## [Unreleased] - ReleaseDate
44

5+
- Report full source file paths in egglog span and error messages.
56
- Desugar `relation`s to `constructor`s to simplify the language and implementation. Relations no longer return unit `()` values.
67
- Refactored API to use [`TermId`] more consistently instead of `Term` where possible, simplifying egglog code.
78
- **Typed primitive surface for seminaive safety (#772).** Custom primitives now pick one of `PurePrim` / `ReadPrim` / `WritePrim` / `FullPrim` based on what the body needs, and register via the matching `add_*_primitive`. Rust enforces capability bounds via the state wrapper passed to the body; the egglog typechecker enforces context bounds. See the `egglog::exec_state` module docs and the `*Prim` trait docs for the full picture. Migration: `rust_rule` callbacks now take `&mut WriteState` (replacing `RustRuleContext`); a new `rust_rule_full` gives action callbacks read access. Higher-order primitives over `unstable-fn` values dispatch via `state.apply_function(&fc, args)`.

egglog-ast/src/span.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,7 @@ impl Display for Span {
7474
.file
7575
.get_location((span.j.saturating_sub(1)).max(span.i));
7676
let quote = self.string();
77-
// Use just the file name, not the full path, for cross-platform consistency in snapshots
78-
let display_name = span.file.name.as_ref().map(|path| {
79-
std::path::Path::new(path)
80-
.file_name()
81-
.and_then(|n| n.to_str())
82-
.unwrap_or(path)
83-
});
84-
match (&display_name, start_line == end_line) {
77+
match (&span.file.name, start_line == end_line) {
8578
(Some(filename), true) => write!(
8679
f,
8780
"In {start_line}:{start_col}-{end_col} of {filename}: {quote}"
@@ -102,3 +95,23 @@ impl Display for Span {
10295
}
10396
}
10497
}
98+
99+
#[cfg(test)]
100+
mod tests {
101+
use super::*;
102+
103+
#[test]
104+
fn egglog_span_display_preserves_full_path() {
105+
let path = "/tmp/egglog/full/path/example.egg".to_string();
106+
let span = Span::Egglog(Arc::new(EgglogSpan {
107+
file: Arc::new(SrcFile {
108+
name: Some(path.clone()),
109+
contents: "(bad)".to_string(),
110+
}),
111+
i: 0,
112+
j: 5,
113+
}));
114+
115+
assert_eq!(span.to_string(), format!("In 1:1-5 of {path}: (bad)"));
116+
}
117+
}

tests/files.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ impl Run {
2222
self.path.parent().unwrap().ends_with("proofs")
2323
}
2424

25+
fn filename_for_test_run(&self) -> Option<String> {
26+
if self.should_fail() {
27+
// Fail-typecheck errors are snapshot-tested. Pass a stable display
28+
// name so Span can render the caller-provided path verbatim without
29+
// making snapshots depend on the local checkout path.
30+
self.path
31+
.file_name()
32+
.map(|name| name.to_string_lossy().into())
33+
} else {
34+
self.path.to_str().map(String::from)
35+
}
36+
}
37+
2538
/// Extraction results may differ slightly due to the proof encoding when multiple
2639
/// solutions have the same cost. Snapshot only the extracted cost so shared
2740
/// snapshots still verify that normal and proof modes find equally good solutions.
@@ -51,7 +64,7 @@ impl Run {
5164

5265
let result = if !self.desugar {
5366
self.test_program(
54-
self.path.to_str().map(String::from),
67+
self.filename_for_test_run(),
5568
&program,
5669
"",
5770
"Top level error",

0 commit comments

Comments
 (0)