fix(diagnostics): locate import parse errors in the imported file
A parse error raised while resolving an `#import` was rendered against the ROOT file's source — the caret landed on an unrelated line (often a comment) even though the message named the correct imported file. Two compounding causes: - core.zig wired `diagnostics.import_sources` only AFTER import resolution returned, but a parse error aborts mid-resolution (before that wiring), so the renderer had no imported sources and fell back to the root file. Wire it (and seed the main-file source) BEFORE resolving. - imports.zig emitted the diagnostic at the importer's `#import` span instead of the parser's actual error offset inside the imported file, and didn't pin the diagnostic's source_file to that file. parser.zig now records `err_end` alongside `err_offset` for a proper caret width. New `DiagnosticList.addFmtInFile` renders against an explicit source file; imports.zig uses it with `importErrSpan(&p)`. Regression test: examples/1176-diagnostics-import-parse-error-location (importer + deliberately-broken companion; caret must land in the companion).
This commit is contained in:
17
src/core.zig
17
src/core.zig
@@ -106,6 +106,16 @@ pub const Compilation = struct {
|
||||
var chain = std.StringHashMap(void).init(self.allocator);
|
||||
var cache = imports.ModuleCache.init(self.allocator);
|
||||
const base_dir = imports.dirName(self.file_path);
|
||||
|
||||
// Wire import_sources to diagnostics BEFORE resolving imports, so a parse
|
||||
// error in an imported file (reported mid-resolution, which then aborts
|
||||
// before the post-resolution wiring below) can resolve its caret against
|
||||
// the imported file's OWN source. The map pointer is stable; per-file
|
||||
// entries fill in as imports load. The main-file source is seeded here
|
||||
// too so a root-file diagnostic resolves identically.
|
||||
self.import_sources.put(self.file_path, self.source) catch {};
|
||||
self.diagnostics.import_sources = &self.import_sources;
|
||||
|
||||
const mod = imports.resolveImports(
|
||||
self.allocator,
|
||||
self.io,
|
||||
@@ -145,11 +155,8 @@ pub const Compilation = struct {
|
||||
// `namespace_edges` in place to record each target's member ids.
|
||||
self.decl_table = try imports.buildDeclTable(self.allocator, self.file_path, mod, &cache, &self.module_decls, &self.namespace_edges);
|
||||
|
||||
// Store main file source in import_sources so error reporting can find it
|
||||
self.import_sources.put(self.file_path, self.source) catch {};
|
||||
|
||||
// Wire import_sources to diagnostics for file-aware error rendering
|
||||
self.diagnostics.import_sources = &self.import_sources;
|
||||
// (import_sources ↔ diagnostics wiring + main-file seed now done before
|
||||
// resolution, above, so mid-resolution parse errors render correctly.)
|
||||
|
||||
// Build a root node from the resolved module's decls
|
||||
const new_root = try self.allocator.create(Node);
|
||||
|
||||
Reference in New Issue
Block a user